4.1 Spring 5.0新特性
4.1.1 运行环境
Spring 5.0正常运行时,需要以下环境:
• 整个Spring框架的代码基于JDK 8开发。当读者选择升级Spring框架时,需要先确认已经安装了JDK 8及以上的JDK版本,否则Spring 5.0将不能正常运行。
• Spring 5.0通过使用泛型推断和lambda表达式等特性提高了代码的可阅读性。
• 支持使用Java 8编程。
• 支持JDK 9开发部署。
• 整个Spring 5.0框架在JDK 9环境下编译和测试通过(默认是运行在JDK 8上的)
• Spring 5.0的相关特性需要Java EE 7 API。
• 支持Servlet 3.1、Bean Validation 1.1、JPA 2.1、JMS 2.0、Tomcat 8.5+、Jetty 9.4+、WildFly 10+。
• Spring 5.0在运行时兼容Java EE 8。
• 兼容Servlet 4.0、Bean Validation 2.0、JPA 2.2、JSON Binding API 1.0、Tomcat 9.0、Hibernate Validator 6.0、Apache Johnzon 1.1。
4.1.2 删除的代码
涉及删除的地方有beans.factory.access、jdbc.support.nativejdbc、mock.staticmock、web.view.tiles2、orm.hibernate3/hibernate4,另外Spring 5.0不再支持Portlet、Velocity、JasperReports、XMLBeans、JDO、Guava,除此之外,Spring 5.0将许多废弃的类和方法删除了。因此,读者在生产实践中升级Spring 5需要关注以上这些代码的删除是否对已有的业务有影响,做出适合自己的升级方案。
4.1.3 核心修改
Spring 5.0核心修改如下。
• 基于Java 8反射增强的实现高效的方法参数访问。
• 选择性地对Spring核心接口使用Java 8默认方法的声明。
• 尽可能避免使用JDK 9废弃的API。
• 通过构造函数实现一致的实例化(修改后的异常处理)。
• 对核心JDK类的反射防御性使用。
• 使用“@Nullable”明确注解可以为空的参数、字段和返回值。
• 访问资源Resource类提供getFile和isFile防御式抽象。
• Resource接口中提供基于NIO的readableChannel的访问器。
• 通过NIO 2.0流进行文件系统访问(不再使用BIO FileInput/OutputStream)。
• Spring 5框架自带了通用的日志组件。
• spring-jcl替代了通用的日志。
• 无需任何额外桥接即可自动检测Log4j 2.x、SLF4J、JUL(java.util.logging)。
• spring-core附带ASM 6.0。
4.1.4 核心容器更新
Spring 5.0的核心容器更新如下。
• 支持@Nullable注解。
• GenericApplicationContext/AnnotationConfigApplicationContext支持函数式风格编程。
• 基于Supplier的bean注册API,可以为bean定制回调。
• 在接口层面使用CGLIB动态代理时,提供事物、缓存、异步注解检测。
• XML配置命名空间简化为无版本化的模式,始终使用最新的xsd文件,不支持已弃用的功能,指定版本的声明仍然支持,但针对最新架构进行了验证。
• 支持候选组件索引(作为类路径扫描的替代方案)。
4.1.5 Spring Web MVC更新
Spring Web MVC更新如下。
• Spring 5.0中的Filter实现了Servlet 3.1签名支持。
• 支持Spring MVC控制器方法中使用Servlet 4.0 PushBuilder参数。
• 通过委托MediaTypeFactory统一支持常见媒体类型,取代了Java Activation Framework。
• 更新了不可变对象的数据绑定(Kotlin/Lombok/@ConstructorPorties)
• 支持JSON绑定API(使用Eclipse Yasson或Apache Johnzon代替Jackson和GSON)。
• 支持Jackson 2.9。
• 支持Protobuf 3。
• 支持Reactor 3.1 Flux、Mono和RxJava 1.3/RxJava 2.1作为Spring MVC控制器方法的返回值,目标是使用新的反应式WebClient或Spring MVC控制器中的Spring Data Reactive存储库。
• 用新的ParsingPathMatcher代替AntPathMatcher,得到更高效的解析和扩展语法。
• @ExceptionHandler方法允许使用RedirectAttributes参数(以及flash属性)。
• 支持ResponseStatusException作为“@ResponseStatus”的代替方案。
• 通过使用ScriptEngine中的eval(String,Bindings)方法直接呈现脚本,以及通过新的RenderingContext参数在ScriptTemplateView中使用i18n和嵌套模板,支持不需要实现Invocable的脚本引擎。
• Spring的FreeMarker宏(spring.ftl)现在使用HTML输出格式(需要FreeMarker 2.3.24+)。
4.1.6 Spring WebFlux
Spring 5.0新增加了Spring WebFlux模块,其特性如下。
• 新的spring-webflux模块是一个基于reactive的代替spring-webmvc的模块,完全的异步非阻塞,旨在使用event-loop执行模型替代传统的大线程池,每个线程处理一个请求的模型。
• spring-core相关的基础组件,比如Encode和Decoder可以用来编码和解码数据流;DataBuffer可以使用Java中的ByteBuffer或者Netty中的ByteBuf作为数据缓冲区:ReactiveAdapterRegistry可以对相关的库提供传输层支持。
• 在spring-web包里包含HttpMessageReade和HttpMessageWrite,其委托给Encoder和Decoder“@Controller”基于注解的编程模型,类似于Spring MVC,在WebFlux中支持在反应堆栈上运行,例如能够支持反应类型作为控制器方法参数,非阻塞IO,并可以在其他的非Servlet容器(如Netty和Undertow)上运行。
• 新的函数式编程模型WebFlux.fn作为“@Controller”基于注解编程模型的替代方案,使用端点路由API进行最小化和透明化,在相同的反应堆栈和WebFlux基础架构上运行。
• 新的WebClient具有用于HTTP调用的功能和响应式API,与RestTemplate相当,但通过流畅的API,并且在基于WebFlux基础架构的非阻塞和流式方案中也表现出色,在Spring 5中,不推荐使用AsyncRestTemplate,而是推荐使用WebClient。
4.1.7 对Kotlin的支持
Spring 5.0对Kotlin的支持如下。
• 使用Kotlin1.1.50或更高版本时,可以支持Null安全的API。
• 支持带有可选参数和默认值的Kotlin不可变类。
• 支持使用Kotlin DSL定义函数式Bean。
• 支持在WebFlux中使用有路由功能的Kotlin DSL。
• 利用Kotlin reified的类型参数来避免在各种API(如RestTemplate或WebFlux API)中明确指定用于序列化/反序列化的Class。
• 对@autowired、@Inject、@RequestParam和@RequestHeader等注解的Kotlin null安全支持,以确定注入点或处理程序方法参数是否合法。
• ScriptTemplateView中的Kotlin脚本支持Spring MVC和Spring WebFlux。
• 支持带有可选参数的Kotlin自动装配构造函数。
• Kotlin反射用于确定接口方法参数。
4.1.8 测试改进
Spring 5.0测试改进如下。
• 在Spring TestContext Framework中完全支持JUnit 5 Jupiter编程和扩展模型。
• SpringExtension:是JUnit Jupiter的多个扩展API的实现,它为Spring TestContext Framework的现有功能集提供完全支持。通过@ExtendWith(SpringExtension.class)启用此支持。
• @SpringJUnitConfig:一个复合注释,它将来自JUnit Jupiter的“@ExtendWith(SpringExtension.class)”与来自Spring TestContext Framework的“@ContextConfiguration”相结合。
• @SpringJUnitWebConfig:一个复合注释,它将来自JUnit Jupiter的“@ExtendWith(SpringExtension.class) ”与来自Spring TestContext Framework的“@ContextConfiguration”和“@WebAppConfiguration”相结合。
• @EnabledIf:如果提供的SpEL表达式或属性占位符的计算结果为true,则表示已启用带注释的测试类或测试方法。
• @DisabledIf:如果提供的SpEL表达式或属性占位符的计算结果为true,则表示禁用带注释的测试类或测试方法。
• 支持Spring TestContext Framework执行并行测试。
• Spring TestContext Framework新增测试之前和测试之后的执行回调功能。
• TestExecutionListener API和TestContextManager新增beforeTestExecution()和afterTestExecution()回调。
• MockHttpServletRequest现在具有用于访问请求体的方法getContentAsByteArray()和getContentAsString()。
• 如果在模拟请求中设置了字符编码,则Spring MVC Test中的print()和log()方法现在会打印请求主体。
• Spring MVC Test中的redirectedUrl()和forwardedUrl()方法现在支持具有可变参数扩展的URI模板。
• XMLUnit支持升级到XMLUnit 2.3。