相关文章推荐
狂野的麦片  ·  Android ...·  2 月前    · 

「Java」 - SpringBoot & 2.1.x版本

2018年3月1号Spring Boot 2.0.0.RELEASE正式发布,这是Spring Boot 1.0发布4年之后第一次重大修订。

一、基础环境升级

最低JDK 8,支持JDK 9,不再支持Java 6和7。

Spring Boot 2.0要求Java 8作为最低版本,许多现有的API已更新,以便于利用Java 8的特性。例如,接口上的默认方法,函数回调以及新的API,如javax.time。

Spring Boot 2.0通过测试可以在JDK 9下正常运行,同时Spring Boot 2.0宣布不再支持Java 6和7,环境还在JDK 7或者6环境下运行,考虑升级Spring Boot 2.0时还需要考虑版本因素。

A、依赖组件升级

Spring Boot 2.0基于Spring Framework 5构建,Spring Boot的升级,同时也升级了部分其依赖的第三方组件,主要有以下几个:

  • Jetty 9.4:Jetty是一个开源的Servlet容器,它为基于Java的web内容,例如JSP和Servlet提供运行环境。Jetty是使用Java语言编写的,它的API以一组Jar包的形式发布。
  • Tomcat 8.5:Apache Tomcat 8.5.x旨在取代8.0.x,完全支持Java 9。
  • Flyway 5:Flyway是独立于数据库的应用、管理并跟踪数据库变更的数据库版本管理工具。用通俗的话讲,Flyway可以像SVN管理不同人的代码那样,管理不同人的SQL脚本,从而做到数据库同步。
  • Thymeleaf 3.0:Thymeleaf 3相对于Thymeleaf 2有非常大的性能提升。
  • Hibernate 5.2
  • Gradle 3.4

二、默认软件替换和优化

A、HikariCP

默认连接池已从Tomcat切换到HikariCP,HikariCP是一个高性能的JDBC连接池,Hikari是日语「光」的意思。

HikariCP号称是Java业界最快的数据库连接池, 官网 提供了c3p0、dbcp2、tomcat、vibur 和Hikari等数据连接池的性能对比。

关于Hikari性能,官网给出的说明如下:

  • 字节码精简:优化代码,直到编译后的字节码最少,这样CPU缓存可以加载更多的程序代码;
  • 优化代理和拦截器:减少代码,例如HikariCP的Statement proxy只有100行代码;
  • 自定义数组类型(FastStatementList)代替ArrayList:避免每次get()调用都要进行range check,避免调用remove()时从头到尾的扫描;
  • 自定义集合类型(ConcurrentBag):提高并发读写的效率;
  • 其他针对BoneCP缺陷的优化,比如对于耗时超过一个CPU时间片的方法调用的研究

B、Security

Spring Security是Spring社区的一个顶级项目,也是Spring Boot官方推荐使用的Security框架。除了常规的Authentication和Authorization之外,Spring Security还提供了诸如ACLs、LDAP、JAAS、CAS等高级特性以满足复杂场景下的安全需求。

没有使用Spring Boot之前集成起来相对比较麻烦,而Spring Boot中基于Java配置实现Spring Security功能。Spring Boot 2.0极大的简化了默认的安全配置,并使添加定制安全变得简单。

Spring Boot 2.0非常容易使用Spring Security 5.0保护响应式应用,当检测到Spring Security存在的时候会自动进行默认配置。

C、OAuth 2.0

OAuth 2.0是OAuth协议的延续版本,但不向后兼容OAuth 1.0,即完全废止了OAuth1.0。OAuth 2.0关注客户端开发者的简易性。

OAuth 2.0是一个授权框架,或称授权标准,它可以使第三方应用程序或客户端获得对HTTP服务上(如Google、GitHub)用户帐户信息的有限访问权限。OAuth 2.0通过将用户身份验证委派给托管用户帐户的服务以及授权客户端访问用户帐户进行工作。

Spring Boot 2.0将Spring Security OAuth项目迁移到Spring Security,不再提供单独的依赖包,Spring Boot 2.0通过Spring Security 5提供OAuth 2.0客户端支持。

D、Micrometer

Micrometer是一款监控指标的度量类库,可以在没有供应商锁定的情况下对JVM的应用程序代码进行调整。

Spring Boot 2.0增强了对Micrometer的集成,不再提供自己的指标API。依靠 micrometer.io 来满足所有应用程序监视需求。Micrometer包括尺寸指标的支持,当与尺寸监测系统配对时,尺寸指标可以有效访问特定的指定度量标准,并且可以在其尺寸范围内向下钻取。

指标可以输出到各种系统和开箱即用的Spring Boot 2.0,为Atlas、Datadog、Ganglia、Graphite、Influx、JMX、New Relic、Prometheus、SignalFx、StatsD和Wavefront提供支持,另外还可以使用简单的内存中度量标准。

集成后提供JVM指标(包括CPU、内存、线程和GC)、Logback、Tomcat、Spring MVC

E、Redis默认使用Lettuce

Redis方面默认引入了Lettuce,替代了之前的Jedis作为底层的Redis连接方式。

Lettuce是一个可伸缩的线程安全的Redis客户端,用于同步、异步和反应使用。多个线程可以共享同一个RedisConnection,它利用优秀Netty NIO框架来高效的管理多个连接,支持先进的Redis功能,如Sentinel、集群、流水线、自动重新连接和Redis数据模型。

F、配置属性绑定

在Spring Boot 2.0中,使用@ConfigurationProperties的绑定机制被重新设计,限制了绑定规则,并修复了Spring Boot 1.x中的许多不一致的地方。

新的Binder API也可以直接使用@ConfigurationProperties在代码中。例如,下面绑定List中的PersonName对象:

List people = Binder.get(environment)
                    .bind("my.property", Bindable.listOf(PersonName.class))
                    .orElseThrow(IllegalStateException::new);

配置源可以像这样在YAML中表示:

my:  
  property: 
    first-name: Jane   
    last-name: Doe  

G、Actuator改进

在Spring Boot 2.0中Actuator endpoints有很大的改进,所有HTTP Actuator endpoints现在都在该/actuator路径下公开,并且生成的Json有效负载得到了改进。

现在默认情况下不会暴露很多端点。如果从Spring Boot 1.5升级现有的应用,请务必查看迁移指南并特别注意该management.endpoints.web.exposure.include属性。

H、测试

Spring Boot 2.0中测试进行了一些补充和调整:

  • @WebFluxTest已添加新注释以支持WebFlux应用程序的slice测试;
  • Converter和GenericConverter beans现在自动扫描@WebMvcTest和@WebFluxTest;
  • @AutoConfigureWebTestClient已经添加到WebTestClient供测试使用,这个注释会自动应用于@WebFluxTest测试;
  • 增加了一个新的ApplicationContextRunner测试实用程序,可以很容易的测试自动配置,大部分内部测试套件已移至此新模型。

三、新技术的引入

A、HTTP/2

HTTP/2是第二代HTTP协议,Spring Boot的Web容器选择中Tomcat、Jetty均已支持HTTP/2。

相比HTTP/1.x,HTTP/2在底层传输做了很大的改动和优化:

  • HTTP/2采用二进制格式传输数据,而非HTTP/1.x的文本格式,二进制格式在协议的解析和优化扩展上带来更多的优势和可能。
  • HTTP/2对消息头采用HPACK进行压缩传输,能够节省消息头占用的网络的流量;而HTTP/1.x每次请求,都会携带大量冗余头信息,浪费了很多带宽资源;头压缩能够很好的解决该问题。
  • 多路复用,直白的说就是所有的请求都是通过一个TCP连接并发完成。HTTP/1.x虽然通过pipeline也能并发请求,但是多个请求之间的响应会被阻塞的,所以pipeline至今也没有被普及应用,而HTTP/2做到了真正的并发请求。同时,还支持优先级和流量控制。
  • Server Push,服务端能够更快的把资源推送给客户端。例如,服务端可以主动把JS和CSS文件推送给客户端,而不需要客户端解析HTML再发送这些请求,当客户端需要的时候,它已经在客户端了。

B、嵌入式Netty服务器

由于WebFlux不依赖于Servlet API,可以首次将Netty作为嵌入式服务器提供支持,该spring-boot-starter-webflux启动pom将拉取Netty和Ractor Netty。

C、JOOQ的支持

JOOQ是基于Java访问关系型数据库的工具包。JOOQ既吸取了传统ORM操作数据的简单性和安全性,又保留了原生SQL的灵活性,它更像是介于ORM和JDBC的中间层。

D、支持Quartz

Spring Boot 1.0并没有提供对Quartz的支持,出现了各种集成方案,Spring Boot 2.0给出了最简单的集成方式。

E、响应式编程

WebFlux名称中的Flux来源于Reactor中的类Flux。Spring WebFlux有一个全新的非堵塞的函数式Reactive Web框架,可以用来构建异步的、非堵塞的、事件驱动的服务,在伸缩性方面表现非常好,此功能来源于Spring 5.0。

非阻塞的关键预期好处是能够以小的固定数量的线程和较少的内存进行扩展。在服务器端WebFlux支持两种不同的编程模型:

  • 基于注解的@Controller和其他注解也支持Spring MVC;
  • Functional、Java 8 Lambda风格的路由和处理。

默认情况下,Spring Boot 2.0使用Netty WebFlux,因为Netty在异步非阻塞空间中被广泛使用,异步非阻塞连接可以节省更多的资源,提供更高的响应度。通过比较Servlet 3.1非阻塞I/O没有太多的使用,因为使用它的成本比较高,Spring WebFlux打开了一条实用的通路。

F、Kotlin的支持

Spring Boot 2.0现在包含对Kotlin 1.2.x的支持,并提供了runApplication。

四、API变化

A、启动类SpringBootServletInitializer

Spring Boot部署到Tomcat中去启动时需要在启动类添加SpringBootServletInitializer,2.0和1.0有区别。

// 1.0
import org.springframework.boot.web.support.SpringBootServletInitializer;
// 2.0
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
@SpringBootApplication
public class UserManageApplicationextendsSpringBootServletInitializer
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application)
        return application.sources(Application.class);    
    public static void main(String[] args) throws Exception 
        SpringApplication.run(Application.class, args);    

Spring Boot 2.0默认不包含log4j,建议使用slf4j。

import org.apache.log4j.Logger;
protected Logger logger = Logger.getLogger(this.getClass());
// 改为
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
protected Logger logger =  LoggerFactory.getLogger(this.getClass());

B、Thymeleaf 3.0默认不包含布局模块

Spring Boot 2.0中spring-boot-starter-thymeleaf包默认并不包含布局模块,使用Thymeleaf对页面进行布局时,需要单独添加布局模块。

<dependency>
    <groupId>nz.net.ultraq.thymeleaf</groupId>
    <artifactId>thymeleaf-layout-dialect</artifactId>
</dependency>

C、WebMvcConfigurerAdapter过期

Spring Boot 2.0中将原来的WebMvcConfigurerAdapter替换为WebMvcConfigurer。

// 1.0
public class MyWebMvcConfigurerAdapter extends WebMvcConfigurerAdapter