该如何从 Java 8 升级到 Java 10

Java 9 出来了很久,买的书《Java 9 Revealed - For Earyly Adoption and Migration》,说怎么迁移到 Java 9,可是突然间 Java 9 就无法通过正常渠道从 Oracle 官网下载了,这书还让不让人看。当然要看,因为尽管 Java 10 出来了,但实际的变化全压在 Java 9 这个版本上的,就当是通过 Java 10 来学习 Java 9 吧。

本文随便说说 Java 8 之后的版本变迁,不涉及 Java 9 或是 Java 10 的具体新特性,并不能回答标题中的问题。作为一个不甘落后的 IT 从业人员,总是希望能紧跟技术(某一狭小特定领域的技术)的步伐。譬如说当从 Java 1.4 升级到 Java 1.5 之后,对范型也是跃跃欲试,无奈当时公司追求的是稳定压倒一切,不在服务器上升级 JDK,所以只能创造条件也要上。于是弄了个 Retrotranslator让你用JDK1.5的特性写出的代码能在JVM1.4中运行 来适配。

后来的公司,也就是现在更为激进一些,来了 JDK 6,跟; JDK 7,跟; JDK 8, 继续跟; JDK 9 发布后,不跟了。不是不想跟,而是 Java 9 实在是变化有点大,模块化带来的不仅仅语言方面的改变,而是影响到如何组织,发布应用,这也就是为什么 jigsaw 雪藏多年的缘故。其实也可以对模块化不欲理会,但是单纯的把 Java 8 换成 Java 9 造成原来的项目不能正常构建的概率也比以往要高。

Java 8 是 2014 年 3 月发布,四后半后的 Java 9 在 2017 年 9 月发布,然而 2018 年 3 月 Java 10 就出来了。谁说 Oracle 在收购 Java 后就对它不作为了呢?Oracle 在 Java 9 之后开始了 6 个月的发布周期(见 Oracle Java SE Support Roadmap),这让人如何受得了,Oracle 自己也是。更何况我们都没来得急品尝 Java 9 的滋味,Oracle 自己就把 Java 9 的生命周期给结束了,进到 Java 9 的下载而面 Java SE 9 Downloads, 自动会导向到 Java SE 10 的下载页面,想要下载 Java SE 9 的话,只能到历史存档中去找 Java SE 9 Archive Downloads阅读全文 >>

类别: Java/JEE. 标签: . 阅读(1,635). 评论(4) »

使用 SQL Server 的 uniqueidentifier 字段类型

SQL Server 自 2008 版起引入了 uniqueidentifier 字段,它存储的是一个 UUID, 或者叫 GUID,内部存储为 16 个字节。SQL Server 可用两个函数来生成 uniqueidentifier, 分别是 NEWID() 和 NEWSEQUENTIALID(), 后者只能用作字段的默认值。Java 也有一个 UUID 工具类 java.uti.UUID, UUID.randomUUID().toString() 生成一个随机的 UUID 字符串,在 java.util.UUID 也是用两个 long 字段表示内部状态。

SQL Server 的 uniqueidentifier 类型字段表明了内部如何存储,在我们操作它时,它的外在表现形式都是一个固定格式 xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx 的字符串,不区分大小写的。

本文所使用的 SQL Server 是 2017 版,通过 Docker 来启动的

docker run -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=yourStrong(!)Password' -p 1433:1433 -d microsoft/mssql-server-linux:2017-latest

然后我们创建一个带有 uniqueidentifier 类型字段的表 阅读全文 >>

类别: Database, Java/JEE. 标签: , . 阅读(668). 评论(0) »

Mockito 也能 Mock final 类和 final 方法了

以实际 Java 项目中的单元测试 Mock 框架基本是 Mockito 2 了,因为它有一个十分流畅的 API。Mockito  2也为 JUnit 5 配上了 MockitoExtension, 所以 JUnit 5 下使用 Mockito 2 的关节也打通了。但在我们享受 Mockito 2 便利的同时,与 JMockit 相比局限性就很明显,因为 Mockito 2 是通过创建匿名子类来进行 Mock 的,所以任何子类对父类无法突破的方面它都存在。譬如,final 类, final 方法, 私有方法, 静态方法, 构造函数都是无法通过子类型进行重写的。所以除非特别需要,在 Mockito 2 无法胜任时都求助于 JMockit,JMockit 借助于 javaagent 取得了 JVM 的高控制权才得已为所欲为。

当 Mockito 来到了 2.1.0 版本,它也觉得不能对以上所有的限制置若罔闻, 首先带给我们的突破是它也可以 Mock final 类和 final 方法,虽然仍处于孵化器中,但毕竟是应用在单元测试中,能用就很不错了,只要以后不被拿走就行。这是官方对它的介绍 Mock the unmockable: opt-in mocking of final classes/methods

下面我亲自操作一遍,并给出更全方位的测试样例 阅读全文 >>

类别: Java/JEE. 标签: , , . 阅读(2,329). 评论(3) »

JUnit 5 使用 Mockito 2 进行测试

JUnit 5 刚出来那时,也就是第一个版本 5.0.0 时,还不能很好的支持 Mockito 的测试,因为 Mockito 没能跟得那么紧密。那时候 JUnit 5 只能试验性的提供了一个极不正式的 com.example.mockito.MockitoExtension, 看那包名就知道不是来真的,所以决定再等。JUnit 5 不再原生支持 JUnit 4 的 Rule,一切都将是 Extension,那也是要求 Mockito 能够与之俱进。现在等来了,JUnit 5 进化到了 5.2.0, Mockito 也早已有了一个单独的模块 mockito-junit-jupiter 来迎接它。

在 Mockito 2.1.0 的 What's new in Mockito 2 中记述了 JUnit 5 为 Mockito 2 开发了一个 MockitoExtension。追溯到 Mockito 2 的 Release Notes, 我们发现 Mockito 2 官方最早引入 MockitoExtension 的版本是 2.16.3(2018-03023)。我对 Mockito 对 JUnit 5 支持的最新更新是从这个 Pull Request MockitoExtension for JUnit5 得知的。

一句话讲就是现在的 Mockito 2 有原生态的 MockitoExtension 来支援 JUnit 5, 可以非常放心可靠的让 JUnit 5 和 Mockito 2 一起稳定工作。因此前面那个包名带 example 字样的 MockitoExtension 链接也就无效了。 阅读全文 >>

类别: Java/JEE. 标签: , . 阅读(773). 评论(0) »

Springfox 解决在单一资源操作多个方法实现时生成 Swagger 文档的问题

在命名本文的标题都敲打了几分钟时间,问题很简单,然而用简短的一个标题完全描述出来却有点费事。在 Spring MVC 项目结合 Springfox 来生成 Swagger API 文档时,如果一个资源操作因为请求参数的不同而映射到多个 controller 方法,那么 Swagger 可能只能生成某一个 API 条目,其余都被忽略。至于为什么说是 "可能", 可能正好未遵循命名规范而躲过了这一劫。由此引出

我们的问题

我们这里用了资源操作一词,它包含了两部分信息: 资源与操作,比如 /users/{userId} 是资源,而发生在其上的 HTTP 各种方法,如 POST, GET, PUT, DELETE 等就是操作。而 Spring MVC 中允许我们针对不同的查询参数把相同的资源操作映射到不同的 controller 方法上,也是为了保持逻辑上更为清晰。

比如下面的例子路由配置的例子

GET /users/{userId}     UserController.getUserInfo                                    //默认
GET /users/{userId}     UserController.getUserInfo                                   //当有 ?source=file 时
GET /users/{userId}     CloudUserController.getUserInfoFromCloud       //当有 ?source=cloud 时

看到上面资源与操作完全相同,仅仅因为 source 查询参数的不同而映射到三个 controller 方法。用代码体现如下图 阅读全文 >>

类别: Spring. 标签: , , . 阅读(236). 评论(2) »

Spring MVC 项目中用 SpringFox 生成 Swagger2 API 文档

前面写过一篇如何建立 一个最基础的 Spring 4 MVC Maven 项目,现在是要在此基础上使用 SpringFox 来生成 Swagger 文档以及 SwaggerUI。Swagger 2 是基于 OpenAPI3.0 的实现,SpringFox 是用于在 Spring 项目中生成 Swagger 文档及 UI, 主要包括两个组件 springfox-swagger2 和  springfox-swagger-ui

本文是基于普通的 Spring MVC 项目的实例,而非针对 SpringBoot 项目,实际运用应该大同小异,无外乎 SpringBoot 中有许多自动配置项。并且本文也不涉及到 Swagger 众多注解的具体用法,具体请查看源代码或相关文档。

开始本文的示例,首先需要搭建起 Spring MVC 项目,具体做法请参考  一个最基础的 Spring 4 MVC Maven 项目

对应于两个组件 springfox-swagger2 和 springfox-swaager-ui 的应用,从大尺度上讲有两方面的内容,分别是

一:生成 Swagger 2 的 JSON API 文档

使用第一个组件 springfox-swagger2 能够让项目运行期自动生成 Swagger 2 的 JSON API 文档,分两步走

添加 springfox-swagger2 依赖

在项目的 pom.xml 文件中加入依赖配置

截止目前,springfox 官方已释放出 springfox-swagger2:2.9.0, 但是在 Maven 的中央仓库中只有 2.8.0 版,所就采用 2.8.0 版本 阅读全文 >>

类别: Spring. 标签: . 阅读(382). 评论(7) »

一个最基础的 Spring 4 MVC Maven 项目

这是一个最基本的 Spring 4 MVC 的 Maven 项目,非 SpringBoot 的,SpringBoot 由于有许多自动化配置特性,会更简单些。本例全部用 Java 代码作为配置,免除了创建 web.xml 和如 dispatcher-servlet.xml 这样的文件。本人更倾向于 Java 配置,它的优势在于能进行编译期检查,逻辑性也强,配置文件只是改动无需重新编译,都是要重启服务的; 关于使用 XML 配置文件的方式可参考文后的链接。

本文侧重于 Spring MVC 项目提供 RESTful JSON API, 因而静态 Web 内容提及较少。创建一个 Maven 项目的方式,可以直接创建一个 pom.xml 文件,然后编辑它的内容,使用 IntelliJ IDEA 的话只需要选择导入为一个 Maven 项目就成,Eclipse 的话可能还要事先运行 mvn eclipse:eclipse 初始化一下。

项目结构布局

就是一个普通的 Maven 项目,稍稍不同的是 src/main 目录中除了 java 和 resources 之外,还有 webapp 目录,用于存放 web 静态文件或模板文件的。 阅读全文 >>

类别: Spring. 标签: . 阅读(129). 评论(1) »

Scala 自身类型(self-type) 解析

Scala 有一个自身类型(self-type) 的东西,由来已久,居然今天才发现。如果一个类或 trait 指明了 self-type 类型(包括类和特质),它的子类型或是对象也必须是相应的类型。它产生的效果与继承(或 mixin) 颇有几分相似。self-type 的语法是 this 的别名: 某一类型(class 或 trait), 直接看一个例子:

上面 this: User => 中的 this 只是一个别名,可以是 self 或任何有效标识(如  abc: User),这里使用 this 等于未指定别名,与原本的 this 重叠了。如果声明为非 this 的话则可以这么用 阅读全文 >>

类别: Scala. 标签: . 阅读(125). 评论(0) »

Akka Actor: 从最简单的例子开始

Akka 是什么?它提供了 JVM 上的 Actor 编程模型 -- 同时兼顾了并发与分布式。它由 Scala 编写的,替代了 Scala 本身的 Actor。Actor 视线程为重量级的资源,能够以少量的内存胜任更高的并发,类似的东西有纤程,协程。有一个数据对比是同样的 1GB 内存,可以创建 2.7M 个 Actor, 而线程只能创建 4096 个,仅供参考,当然 Java 也是会基于线程池来执行的。

Actor 增加了程序的灵活性,并减轻了复杂度(标准的赞美之辞)。

所谓 Action 编程模型兼顾并发与分布,是由于让你编程时可以不用考虑线程,线程配置成为部署的范畴; Actor 之间通信只能发送异步消息,Actor 可以分布在同一 JVM, 不同 JVM, 或是不同物理机器上。

因为 《Akka IN ACTION》中提供了第一个例子起点着实有点高,所以网上找来了一个了解 Akka Actor 的最简单例子,来自于 Simple Scala Akka Actor examples (Hello, world examples)。并非纯属翻译,主要是为了练手,所以不完全一致: 阅读全文 >>

类别: Akka, Scala. 标签: , , . 阅读(695). 评论(0) »

并发(Concurrent) 与并行(Parallel) 的区别

刚开始阅读 《Akka IN ACTION》这本书,刚开始是对 Revolution 这个词翻译成中文是革命 感到诧异,因为革命 通俗来讲就是 杀人 的意思。至于 Revolution 英文解释不深究了,只是感叹何以颠覆性的变化就一定要杀人吗?

也由此引出了编程中经常面对的 Concurrent(名词为:Concurrency) 和 Parallel(名词为:Parallelism) 这两个词,基本上是认为它们是同一个意思。其实不然,下面慢慢道来。

如果从英文字典对它们的解释也没有多大区别,差不多都是说同是发生,但字面上 Parallel 多了一个平行的意思。所以在中文上,在计算机领域我们约定的翻译是

  • Concurrent(Concurrency)  --  并发
  • Parallel(Parallelism)           --  并行

比如在多线程环境中它们的区别具体体现在:

并发:多个任务在同一个 CPU 核上按细分的时间片轮流(交替)执行,从逻辑上来看那些任务是同时执行。针对 CPU 内核来说,任务仍然是按细粒度的串行执行。也难怪在 Java 5 中新加的并发 API 的包名是 java.uti.concurrent阅读全文 >>

类别: Java/JEE. 标签: . 阅读(1,576). 评论(2) »