第二部分 Spring Framework 4.x中有什么新功能?
3. Spring Framework 4.0中的新功能和增强功能
Spring框架于2004年首次发布; 从发布至今,已经有了较大的更改:Spring 2.0提供了XML命名空间和AspectJ支持; Spring 2.5采用注释驱动配置; Spring 3.0在框架代码库中引入了强大的Java 5+基础,以及基于Java的@Configuration
模型等功能。
版本4.0是Spring Framework的最新版本,也是第一个完全支持Java 8功能的版本。您仍然可以使用Spring与旧版本的Java,但是,最低要求已经提升到Java SE 6.我们还利用主要版本的机会删除了许多不推荐的类和方法。
可以在Spring框架的GitHub参考上查看项目升级到Spring4.0的指南。
3.1改进入门经验
新的spring.io网站提供了一整套 “入门指南”,帮助您学习Spring。您可以在本文档的第1 章“入门指南”部分阅读有关指南的更多信息。新网站还全面概述了Spring范围内发布的许多其他项目。
如果您是Maven用户,您可能还会对每个Spring 框架Release
版本最新发布的POM物料清单感兴趣。
3.2删除已弃用的软件包和方法
所有已弃用的软件包以及许多不推荐使用的类和方法,均已经从版本4.0中删除。如果您从以前版本的Spring升级,您应该确保您已经修复了对过期的API所做的任何已弃用的调用。
有关完整的更改,请查看API差异报告。
请注意,可选的第三方依赖关系已经提升到2010/2011最低限度(即Spring 4通常只支持2010年底或更晚版本发布的版本):特别是Hibernate 3.6+,EhCache 2.1+,Quartz 1.8+,Groovy 1.8+和Joda-Time 2.0+。作为规则的一个例外,Spring 4需要最近的Hibernate Validator 4.3+,并且对Jackson的支持已经集中在2.0+以上(Jackson 2.8 / 1.9支持保留在Spring 3.2的时候),现在只是不赞成的形式)。
3.3 Java 8(以及6和7)
Spring Framework 4.0支持多种Java 8功能。您可以使用带有Spring的回调接口的 lambda表达式和方法引用。对java.time
(JSR-310)有一流的支持,并且几个现有的注释已经被改装为@Repeatable
。您还可以使用Java 8的参数名称发现(基于-parameters
编译器标志)作为在启用调试信息的情况下编译代码的替代方法。
Spring与旧版本的Java和JDK兼容:具体来说,对Java SE 6(具体来说,与2010年1月发布的JDK 6更新18的最低等级相同)及以上版本仍然完全支持。但是,对于基于Spring 4的新开发项目,我们建议使用Java 7或8。
3.4 Java EE 6和7
Java EE 6+及其相关的JPA 2.0和Servlet 3.0,被认为是Spring 4的基准。为了与Google App Engine和较旧的应用服务器保持兼容,可以将Spring 4应用程序部署到Servlet 2.5环境中。但是,强烈建议部署环境使用Servlet 3.0+,这是测试设置的Spring和模拟软件开发环境的先决条件。
如果您是WebSphere 7用户,请确保安装JPA 2.0功能包。在WebLogic 10.3.4或更高版本上,安装随附的JPA 2.0修补程序。这可以把这两个服务器代码转变成Spring 4兼容的部署环境。
在更前瞻性的笔记中,Spring Framework 4.0现在支持Java EE 7级别的适用规范:特别是JMS 2.0,JTA 1.2,JPA 2.1,Bean Validation 1.1和JSR-236并发实用程序。像往常一样,这种支持侧重于个人使用这些规范,例如在Tomcat或独立环境中。但是,当将Spring应用程序部署到Java EE 7服务器时,它的工作效果同样好。
请注意,Hibernate 4.3是一个JPA 2.1的提供者,因此仅支持Spring Framework 4.0。同样适用于Hibernate Validator 5.0作为Bean Validation 1.1的提供者。因此,Spring Framework 3.2不支持这两种程序。
3.5 Groovy Bean定义DSL
从Spring Framework 4.0开始,可以使用Groovy DSL定义外部bean配置。这在概念上类似于使用XML bean定义,但允许更简洁的语法。使用Groovy还可以方便地将bean定义直接嵌入到引导代码中。例如:
def reader = new GroovyBeanDefinitionReader(myApplicationContext)
reader.beans {
dataSource(BasicDataSource) {
driverClassName = "org.hsqldb.jdbcDriver"
url = "jdbc:hsqldb:mem:grailsDB"
username = "sa"
password = ""
settings = [mynew:"setting"]
}
sessionFactory(SessionFactory) {
dataSource = dataSource
}
myService(MyService) {
nestedBean = { AnotherBean bean ->
dataSource = dataSource
}
}
}
有关更多信息,请查阅GroovyBeanDefinitionReader
javadoc。
3.6 核心集装箱改造
对核心容器进行了如下改进:
- 当注入Bean时,Spring把泛型当作限定符。如果您使用Spring的Repository时,可以轻松地注入特定的实现,例如:
@Autowired Repository<Customer> customerRepository
。 - 使用Spring的元注解,可以开发暴露特定属性的自定义注解。
- Bean可以在被装配到list或数组中时排好序。通过
@Order
注解和Ordered
接口支持。 -
@Lazy
注解可以用于注入点,也可用于@Bean
定义上。 - 引入了
@Description
注解以便开发者使用基于Java的配置。 - 通过
@Conditional
注解可以定义有条件过滤的bean。这与@Profile
类似但允许用户自定义开发策略。 - 基于CGLIB的代理类不再需要默认的构造方法。通过objenesis库进行支持,它被重新打包到Spring中并作为Spring框架的一部分发布。使用这种策略,生成代理实例时没有构造方法将被调用。
- 添加了管理时区的支持。例如
LocaleContext
。
3.7一般Web改进
Spring Framework 4.0仍然可以部署到Servlet 2.5服务器,但现在的部署环境已经主要集中在Servlet 3.0+环境上了。如果您使用 Spring MVC测试框架,则需要确保Servlet 3.0兼容的JAR位于测试类路径中。
除了稍后提到的WebSocket
支持外,Spring的Web模块还进行了以下一般性的改进:
- 您可以在Spring MVC应用程序中使用新的
@RestController
注释,这样就不需要添加@ResponseBody
到每个@RequestMapping
方法中。 - 新增了
AsyncRestTemplate
类,支持开发REST客户端时实现异步非阻塞。 - 在开发Spring MVC应用程序时,Spring会提供全面的时区支持。
3.8 WebSocket,SockJS和STOMP消息传递
新的spring-websocket
模块为Web应用程序中的客户端和服务器之间的基于WebSocket
的双向通信提供了全面的支持。它与 JSR-356、Java WebSocket API兼容,此外还提供了基于SockJS的后备选项(即WebSocket仿真),用于尚不支持WebSocket协议的浏览器(例如Internet Explorer <10)。
新的spring-messaging
模块增加了对STOMP的支持,作为应用中的WebSocket子协议以及用于从WebSocket客户端路由和处理STOMP消息的注释编程模型。其结果是一个@Controller
现在可以同时包含@RequestMapping
和@MessageMapping
方法用于从网页套接字连接的客户端处理HTTP请求和消息。新的spring-messaging
模块还包含关键的抽象概念,以前多由 Spring集成项目,例如Message
,MessageChannel
,MessageHandler
,和其他人作为基于消息的应用奠定了基础。
有关更多详细信息,包括更全面的介绍,请参阅第26章WebSocket支持部分。
3.9测试改进
除了在spring-test
模块中修剪已弃用的代码之外,Spring Framework 4.0还引入了用于单元和集成测试的几个新功能。
spring-test
模块中的几乎所有注释(例如,@ContextConfiguration
, @WebAppConfiguration
,@ContextHierarchy
,@ActiveProfiles
,等),现在可以被用作元注释来创建自定义组成的注解和减少整个测试套件构造重复。
活动bean定义配置文件现在可以通过编程方式解决,只需通过实现自定义ActiveProfilesResolver
并通过@ActiveProfiles
注册resolver
属性即可。
在spring-core
模块中引入了新的SocketUtils
类,可以在本地主机上扫描空闲的TCP和UDP服务器端口。此功能不是专门用于测试,但在编写需要使用套接字的集成测试(例如启动内存中的SMTP服务器,FTP服务器,Servlet容器等)时,可能会非常有用。
从Spring 4.0开始,org.springframework.mock.web
中的mocks
设置,变更为基于Servlet 3.0 API。此外,若干在Servlet API mocks
(例如,MockHttpServletRequest
,MockServletContext
等等)已被更新了少量的增强部分,并且改进其可配置性。
4. Spring框架4.1中的新功能和增强功能
4.1 JMS改进
Spring 4.1引入了一个更简单的基础设置,通过使用@JmsListener
注释bean方法,来注册JMS侦听器端点。XML命名空间设置也支持这种新的配置方式(jms:annotation-driven
),同样,我们可以使用Java的配置文件,完全配置基础设置(@EnableJms
,JmsListenerContainerFactory
)。也可以使用JmsListenerConfigurer
编程方式注册侦听器端点 。
Spring 4.1还与JMS支持对齐,让您从Spring 4.0中的spring-messaging
4.0中引入其抽象介绍,即:
- 消息侦听器端点可以具有更灵活的签名,并受益于标准消息传递注释,如
@Payload
,@Header
,@Headers
,@SendTo
。也可以使用标准Message
代替javax.jms.Message
方法参数。 - 新的
JmsMessageOperations
接口已经可用,并允许JmsTemplate像使用
Message`抽象的操作一样。
最后,Spring 4.1提供了额外的其他改进:
-
JmsTemplate
支持同步请求/回复操作 - 可以为每个
<jms:listener/>
元素指定监听优先级 - 使用
BackOff
实现可配置消息侦听器容器的恢复选项 - 支持JMS 2.0消费共享
4.2缓存改进
Spring 4.1支持使用Spring现有缓存配置的JCache(JSR-107)注释和基础设施抽象;如果使用标准注释,则不需要更改。
Spring 4.1同样显着提高了自身的缓存抽象:
- 缓存可以在运行时使用a级缓存解析器
CacheResolver
解析。因此,也不再强制使用值参定义缓存名。 - 可自定义更多的操作级:缓存解析器,缓存管理器,密钥生成器
- 新的
@CacheConfig
类级注释允许在类级别共享通用设置,而不启用任何高速缓存操作。 - 使用CacheErrorHandler实现更好的缓存异常处理方法
Spring 4.1中还有一个突破性的修改,就是在缓存接口新增了一个putIfAbsent
方法
4.3 Web改进
- 在ResourceHttpRequestHandler的基础上,拓展了资源处理的存在性支持,新增了拓展对象:
ResourceResolver
,ResourceTransformer
和ResourceUrlProvider
。许多内置的实现提供对版本化的资源URL的支持(用于有效的HTTP缓存),查找gzip压缩的资源,生成HTML 5 AppCache清单等等。更多内容见第22.16.9节“资源的服务”。 - JDK 1.8的
java.util.Optional
现在支持@RequestParam
,@RequestHeader
以及@MatrixVariable
控制器的方法参数。 - 基础服务中的
DeferredResult
已经返回的ListenableFuture
被新支持的ListenableFuture
返回值替代(或可能调用AsyncRestTemplate
)。 -
@ModelAttribute
方法现在按照相互依赖关系的顺序进行调用。见SPR-6299。 - Jackson的
@JsonView
在@ResponseBody
和ResponseEntity
控制器方法中被直接支持,用于序列化同一POJO的不同数量的细节(例如摘要与详细页面)。通过将序列化视图类型添加为特殊键下的模型属性,也支持基于视图的渲染。有关详细信息,请参阅“Jackson序列化查看支持”一节。 - Jackson现在支持JSONP。请参阅“Jackson JSONP支持”一节。
- 在控制器方法返回之后和写入响应之前,新的生命周期选项可用于拦截
@ResponseBody
和ResponseEntity
方法。利用声明一个@ControllerAdvice
bean实现ResponseBodyAdvice
。内置的@JsonView
JSONP支持可以利用这一点。请参见第22.4.1节“使用HandlerInterceptor
拦截请求”。 - 有三个新的
HttpMessageConverter
选项:- Gson - 比Jackson更轻的脚本; 已经在Spring Android中使用过。
- Google协议缓冲器 - 作为企业内部的服务间通信数据协议而高效而有效,但也可以作为浏览器的JSON和XML公开。
- 通过
jackson-dataformat-xml
扩展,现在可以支持基于Jackson的XML序列化。当使用@EnableWebMvc
或<mvc:annotation-driven/>
的时候,如果jackson-dataformat-xml
是在类路径下,当会默认使用此方法,而不是JAXB2。
- 像jsp这样的视图现在可以通过使用名称来引用控制器映射来构建到控制器的链接。每个
@RequestMapping
都会分配一个默认名称。例如FooController
,方法handleFoo
名为“FC#handleFoo”。命名策略是可修改的。还可以通过它的name属性明确地命名一个@RequestMapping
。Spring JSP标记库中的一个新增的mvcUrl函数使得在JSP页面命名更加方便。请参见第22.7.2节“构建控制器的URI和视图中的方法”。 -
ResponseEntity
提供了一个构建器式API来指导控制器方法来准备服务器端响应,例如ResponseEntity.ok()
。 -
RequestEntity
是一种新的类型,它提供了一个构建器样式的API来指导客户端REST代码准备HTTP请求。 - MVC Java配置和XML命名空间:
-
Groovy标记模板支持(基于Groovy 2.3)。查看
GroovyMarkupConfigurer
和重新分析视图解析器和“视图”实现。
4.4 WebSocket消息传递改进
- 支持SockJS(Java)客户端。参考
SockJsClient
和同包下的类。 - 当STOMP客户端订阅和取消订阅时,新的应用上下文事件
SessionSubscribeEvent
和SessionUnsubscribeEvent
会被触发。 - 新的作用域“
websocket
”。参考26.4.15 WebSocket作用域。 -
@SendToUser
只能把单会话作为目标,而且不需要用户身份验证。 -
@MessageMapping
方法可以使用点“.”代替斜杠“/”作为分割符。参考SPR-11660。 - STOMP/WebSocket监测信息收集和日志管理。参考26.4.17 运行时监测。
- 得到极大优化和改进的日志管理保留了可读性和简洁性,甚至是在DEBUG的时候。
- 优化了消息的创建,包含了对临时消息可变性的支持,并避免自动消息id和时间戳的创建。参考Javadoc中的
MessageHeaderAccessor
。 - 在WebSocket会话创建60秒后没有活动则将会关闭STOMP/WebSocket连接。参考SPR-11884。
4.5测试改进
- Groovy脚本现在可用于配置
ApplicationContext
,其中ApplicationContext
在测试上下文框架中被加载用于集成测试。- 有关详细信息,请参阅“使用Groovy脚本的上下文配置”一节。
- 测试管理的事务现在可以通过新的
TestTransactionAPI
以编程方式启动并在事务性测试方法中结束。- 有关详细信息,请参阅“程序化事务管理”一节。
- 现在可以通过基于每个类或每个方法的新的
@Sql
和@SqlConfig
注释声明性地配置SQL脚本执行。- 有关详细信息,请参见第15.5.8节“执行SQL脚本”。
- 可以通过新的
@TestPropertySource
注解配置用于测试的property源文件,它能够自动地重写系统和应用的property源文件。- 有关详细信息,请参阅“具有测试属性源的上下文配置”一节。
-
TestExecutionListener
现在可以自动发现默认值。- 有关详细信息,请参阅“
TestExecutionListener
的自动发现”一节。
- 有关详细信息,请参阅“
- 自定义
TestExecutionListener
现在可以自动与默认监听器合并。- 有关详细信息,请参阅“合并
TestExecutionListener
”一节。
- 有关详细信息,请参阅“合并
- TestContext框架中的事务性测试支持文档进行了更全面的解释,并且对其他示例进行了改进。
- 对
MockServletContext
、MockHttpServletRequest
和其他Servlet API模拟的各种改进。 -
AssertThrows
已被重构为支持Throwable而不是Exception。 - 在Spring MVC测试中,可以用JSON断言来断言JSON响应,作为使用JSONPath的额外选项,就像使用XMLUnit可以为XML做的一样。
- 现在可以在
MockMvcConfigurer
的帮助下创建MockMvcBuilder
清单。添加这个功能是为了能够容易应用Spring安全设置,但可以用于封装任何第三方框架或项目中的通用设置。 -
MockRestServiceServer
现在支持AsyncRestTemplate
客户端测试。
5. Spring 4.2框架中的新特性和增强功能
5.1核心容器功能改进
- 诸如在Java 8默认方法中使用@Bean检测和处理的注释,允许使用默认@Bean方法从接口组态配置类。
- 配置类现在可以使用常规组件类声明
@Import
,允许将导入的配置类和组件类混合起来。 - 配置类可以声明一个
@Order
值,即使通过类路径扫描检测到的,也可以以相应的顺序进行处理(例如,通过名称重写bean)。 -
@Resource
注入点支持@Lazy
声明,类似于@Autowired
,接收到被请求的目标bean的延迟初始化代理。 - 应用程序事件基础设施现在提供了一个基于注解的模型,以及发布任意事件的能力。
- 托管bean中的任何公共方法都可以注释
@EventListener
来使用事件。 - @TransactionalEventListener 提供事务绑定事件支持。
- Spring Framework 4.2引入了一流的支持声明和查找注释属性的别名。新
@AliasFor
注释可用于在一个注释中声明一组别名属性或在一个自定义属性组成上的一个属性中声明一个别名去创建一个元数据的一个属性。- 下面的注释已经加装
@AliasFor
,支持他们为其值属性提供有意义的别名:@Cacheable
,@CacheEvict
,@CachePut
,@ComponentScan
,@ComponentScan.Filter
,@ImportResource
,@Scope
,@ManagedResource
,@Header
,@Payload
,@SendToUser
,@ActiveProfiles
,@ContextConfiguration
,@Sql
,@TestExecutionListeners
,@TestPropertySource
,@Transactional
,@ControllerAdvice
,@CookieValue
,@CrossOrigin
,@MatrixVariable
,@RequestHeader
,@RequestMapping
,@RequestParam
,@RequestPart
,@ResponseStatus
,@SessionAttributes
,@ActionMapping
,@RenderMapping
,@EventListener
,@TransactionalEventListener
。 - 例如,
spring-test
模块的@ContextConfiguration
现在声明如下:
- 下面的注释已经加装
public @interface ContextConfiguration {
@AliasFor("locations")
String[] value() default {};
@AliasFor("value")
String[] locations() default {};
// ...
}
- 同样的, 重写了元注解属性的注解现在也可以使用@AliasFor细粒度地控制那些在注解层次结构中被重写的属性。事实上,现在可以给元数据的value属性声明一个别名。
- 例如,现在可以像下面一样开发一种重写了自定义属性的组合注解。
@ContextConfiguration
public @interfaceMyTestConfig {
@AliasFor(annotation = ContextConfiguration.class, attribute = "value")
String[]xmlFiles();
// ...
}
- 参照[Spring注释的编程模型](http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#annotation-programming-model).
- 用于查找元注释的Spring的搜索算法进行了许多改进。例如,在注解继承体系中可以声明局部的组合注解。
- 重写了元注解属性的组合注解现在可以用在接口、抽象类、桥接和接口方法上,也可以用在类、标准方法、构造方法和字段上。
- 代表注解属性的
Map
(和AnnotationsAttributes
实例)可以被合成(或者转换)到一个注解中。 - 基于字段的数据绑定(
DirectFieldAccessor
)可以与当前基于属性的数据绑定(BeanWrapper
)一起使用。特别的,基于字段的绑定现在支持为集合、数据和Map导航。 -
DefaultConversionService
为Steam
、Charset
、Currency
和TimeZone
提供了可以直接使用的转换器。这些转换器也可以被添加到任意的ConversionService
中。 -
DefaultFormattingConversionService
为JSR-354中的货币提供了支持(如果javax.money
存在于classpath
下),即MonetaryAmount
和CurrencyUnit
。这也包含对@NumberFormat
的支持。 -
@NumberFormat
现在可以作为元注解使用。 -
JavaMailSenderImpl
有一个新的方法testConnection()
用于检查与服务器间的连接。 -
ScheduledTaskRegistrar
暴露计划的任务。 - Apache的
commons-pool2
现在支持AOP池CommonsPool2TargetSource
。 - 为脚本化bean引入了
StandardScriptFactory
作为一个基于JSR-223的机制,暴露于XML中的lang:std
元素。对JavaScript和JRuby的支持。(注意:JRubyScriptFactory
和lang:jruby
现在过时了,请使用JSR-223)
5.2 数据访问的改进
- AspectJ现在支持
javax.transactional.Transactional
。 -
SimpleJdbcCallOperations
现在支持命名绑定。 - 全面支持Hibernate ORM 5.0,作为JPA提供者(自动适配),也支持其原生API(被新的
org.springframework.orm.hibernate5
包覆盖)。 - 嵌入的数据库现在可以被自动赋值不同的(unique)名字,且
<jdbc:embedded-database>
支持新的属性database-name
。参考下面的“测试的改进”部分。
5.3 JMS的改进
-
autoStartup
属性可以通过JmsListenerContainerFactory
控制。 - 每个监听器容器都能配置应答
Destination
的类型。 -
@SendTo
注解的值现在可以使用SpEL表达式。 - 响应目标可以使用
JmsResponse
在运行时计算。 -
@JmsListener
是一个可重复性的注解,可以在同一个方法上声明多个JMS容器(如果你还没有使用Java 8,请使用新引入的@JmsListeners
)。
5.4 Web的改进
- 支持HTTP流和服务器发送事件。参考HTTP流。
- 支持内置CORS的全局(MVC Java配置和XML命名空间)和局部(例如,
@CrossOrign
)配置。参考27 CORS支持。 - HTTP缓存更新:
- 新的创建者
CacheControl
,嵌入到ResponseEntity
,WebContentGenerator
,ResourceHttpRequestHandler
中。 - 在
WebRequest
中改进了ETag/Last-Modified的支持。
- 新的创建者
- 自定义映射注解,使用
@RequestMapping
作为元注解。 -
AbstractHandlerMethodMapping
中的公共方法用于在运行时注册和取消注册请求映射。 -
AbstractDispatcherServletInitializer
中的保护方法createDispatcherServlet
进一步自定义DispatcherServlet
的实例。 -
HandlerMethod
作为@ExceptionHandler
方法的参数,特别在@ControllerAdvice
组件中非常便利。 -
java.util.concurrent.CompletableFuture
作为@Controller
方法的返回类型。 -
HttpHeaders
支持字节范围的请求,并提供静态资源。 -
@ResponseStatus
检测嵌套异常。 -
RestTemplate
中的UriTemplateHandler
扩展点。-
DefaultUriTemplateHandler
暴露了baseUrl
属性和路径段编码选项。 - 此扩展点可嵌入到URI模板库中。
-
-
OkHTTP与
RestTemplate
集成。 - 自定义的
baseUrl
可以替代MvcUriComponentsBuilder
中的方法。 - 序列化/反序列化的异常信息在警告级别被记录。
- 默认的JSON前缀从“"{} && " 改成了更安全的")]}', "中的一个。
- 新的扩展点
RequestBodyAdvice
和内置实现支持@RequestBody
方法参数上的Jackson的@JsonView
。 - 使用GSON或Jackson 2.6+时,处理器方法的返回类型被用于改进参数化类型的序列化,比如
List<Foo>
。 - 引入了
ScriptTemplateView
作为JSR-223用于处理脚本web视图的机制,主要关注于Nashorn(JDK 8)上的JavaScript视图模板。
5.5 WebSocket消息处理的改进
- 暴露关于已连接用户和订阅存在的信息。
- 新的
SimpUserRegistry
暴露为叫作“userRegistry”的bean。 - 在服务器集群间共享已存在的信息(参考代理中继配置选项)。
- 新的
- 解决用户在服务器集群中的目的地(参考代理中继配置选项)。
-
StompSubProtocolErrorHandler
扩展点用来定制和控制STOMP错误帧到客户端。 - 通过
@ControllerAdvice
组件声明的全局方法@MessageExceptionHandler
。 - SpEL表达式“selector”头用于
SimpleBrokerMessageHandler
的订阅。 - 通过TCP和WebSocket使用STOMP客户端。参考24.4.14 STOMP客户端。
-
@SendTo
和@SendToUser
可以包含多个占位符。 - Jackson的
@JsonView
支持在@MessageMapping
和@SubscribeMapping
方法上返回值。 -
ListenableFuture
和CompletableFuture
可以作为@MessageMapping
和@SubscribeMapping
方法的返回值类型。 -
MarshallingMessageConverter
用于XML负载。
5.6 测试的改进
- 基于JUnit的集成测试现在可以使用JUnit规则执行而不是
SpringJUnit4ClassRunner
。这使得基于Spring的集成测试可以使用替代runner运行,比如JUnit的Parameterized
或第三方的runner如MockitoJUnitRunner
。 - Spring MVC测试框架现在对HtmlUnit提供了一流的支持,包括集成Selenium的WebDriver,允许基于页面的web应用测试不再需要部署到一个Servlet容器上。
-
AopTestUtils
是一个新的测试工具类,它允许开发者可以获取到底层的隐藏在一个或多个Spring代理类下的目标对象。 -
ReflectionTestUtils
现在支持为static修饰的静态字段设值和取值,包括常量。 - 通过
@ActiveProfiles
声明的bean定义配置文件的原始顺序现在保留了,这是为了使用一些案例,比如Spring Boot的ConfigFileApplicationListener
,它通过有效的名称来加载配置文件。 -
@DirtiesContext
现在支持新的模式BEFORE_METHOD
,BEFORE_CLASS
和BEFORE_EACH_TEST_METHOD
,用于在测试之前关闭ApplicationContext
。——例如,在大型测试套件中的一些劣质的测试毁坏了对ApplicationContext
的原始配置。 -
@Commit
这个新注解可以直接替代@Rollback(false)
。 -
@Rollback
现在可以用来配置类级别默认的回滚语义。- 因此,
@TransactionConfiguration
现在过时了,并且会在后续版本中移除。
- 因此,
- 通过
statements
这个新的属性@Sql
现在支持内联SQL语句的执行。 - 用于在测试期间缓存应用上下文的
ContextCache
现在是公共的API,它有默认的实现,可以替代自定义的缓存需求。 -
DefaultTestContext
,DefaultBootstrapContext
和DefaultCacheAwareContextLoaderDelegate
现在是support
子包下的公共类,允许自定义扩展。 -
TestContextBootstrappers
现在负责创建TestContext
。 - 在Spring MVC测试框架中,
MvcResult
的详细日志现在可以在DEBUG级别被打印,或者写出到自定义的OutputStream
或Writer
中。参考MockMvcResultHanlder
中的新方法log()
,print(OutputStream)
和print(Writer)
。 - JDBC XML的命名空间支持一个新的属性
database-name
,位于<jdbc:embedded-database>
中,允许开发者为嵌入的数据库设置不同的名字——例如,通过SpEl表达式或者被当前有效bean定义配置文件影响的属性文件占位符。 - 嵌入的数据库现在可以被自动赋予不同的名字,允许在同一测试套件不同的应用上下文中重复使用通用的测试数据库配置。
-
MockHttpServletRequest
和MockHttpServletResponse
现在通过getDateHeader
和setDateHeader
方法提供了更好的支持用于格式化日期头。
6. Spring 4.3的新特性和增强功能
6.1 核心容器的改进
- 核心容器提供了更丰富的元数据用于编程式评估。
- Java8的默认方法可以作为bean属性的getter/setter方法被检测。
- 在注入主bean的情况下,不会创建延迟候选bean。
- 如果目标bean仅仅定义了一个构造方法,就不必指定
@Autowired
注解了。 -
@Configuration
类支持构造方法注入。 - 任何用于指定
@EventLIstener
条件的SpEL表达式现在可以引用bean了(例如,@beanName.method()
)。 - 组合注释现在可以使用数组的组件类型的单个元素覆盖元注释中的数组属性。例如,
@RequestMapping
的String[] path
可以使用组合注解的String path
重写。 -
@Scheduled
和@Schedules
可以作为元注解,用来创造组合注解并可重写其属性。 -
@Scheduled
支持任何作用域的bean。
6.2 数据访问的改进
-
jdbc:initialize-database
和jdbc:embedded-database
支持应用于每个脚本的可配置分隔符。
6.3 缓存的改进
spring 4.3 允许并发调用给定的key,从而使得值只被计算一次。这是一项可选功能,通过@Cacheable
的新属性sync启用。这项功能也使Cache接口做了重大改变,增加了get(Object key, Callable<T> valueLoader)
方法。
spring 4.3 也改进了以下缓存方面的内容:
- 缓存相关的注解中的SpEL表达式现在可以引用bean了(比如,
@beanName.method()
)。 -
ConcurrentMapCacheManager
和ConcurrentMapCache
现在可以通过新的属性storeByValue
序列化缓存的entry。 -
@Cacheable
,@CacheEvict
,@CachePut
和@Caching
现在可以作为元注解,用来创造组合注解并可重写其属性。
6.4 JMS的改进
-
@SendTo
现在可应用于类级别上,以便共享共同的目标。 -
@JmsListener
和@JmsListeners
现在可作为元注解,用来创造组合注解并可重写其属性。
6.5 Web的改进
- 内置了对Http头和Http选项的支持。
- 新的组合注解
@GetMapping
,@PostMapping
,@PutMapping
,@DeleteMapping
和@PatchMapping
,它们来源于@RequestMapping
。 - 新的组合注解
@RequestScope
,@SessionScope
和@ApplicationScope
用于web作用域。 - 新的注解
@RestControllerAdvice
,它是@ControllerAdvice
和@ResponseBody
的组合体。 -
@ResponseStatus
现在可用于类级别并可以被所有方法继承。 - 新的
@SessionAttribute
注解用于访问session的属性(查看示例)。 - 新的
@RequestAttribute
注解用于访问request的属性(查看示例)。 -
@ModelAttribute
可以设置其属性binding=false
阻止数据绑定(查看参考)。 -
@PathVariable
可以被声明为可选的(用于@ModelAttribute
方法)。 - 错误和自定义的异常可一致地暴露给MVC的异常处理器。
- Http消息转换器中一致地处理字符集,默认地使用UTF-8处理多部分文本内容。
- 使用已配置的
ContentNegotiationManager
处理媒体类型等静态资源。 -
RestTemplate
和AsyncRestTemplate
可通过DefaultUriTemplateHandler
支持严格的URI编码。 -
AsyncRestTemplate
支持请求拦截。
6.6 WebSocket消息处理的改进
-
@SendTo
和@SendToUser
现在可应用于类级别上,以便共享共同的目标。
6.7 测试的改进
- spring测试上下文中的JUnit现在需要 4.12 及其更高版本。
-
SpringJUnit4ClassRunner
的新别名SpringRunner
。 - 测试相关的注解现在可用于接口上--例如,使用 基于Java 8的接口默认方法的测试接口。
- 如果默认的XML文件、Groovy脚本或
@Configuration
类被检测到,那么空声明的@ContextConfiguration
现在可以完全省略了. -
@Transactional
测试方法不再必需是public了(例如,在TestNG和JUnit 5 中)。 -
@BeforeTransaction
和@AfterTransaction
方法不再必需是public了,并且现在也可能用在Java 8 接口的默认方法上。 - spring测试上下文中的
ApplicationContext
缓存现在是有界的,默认最大值为32,并按最近最少原则回收。其最大值可以通过JVM的系统属性或spring的属性spring.test.context.cache.maxSize
进行设置。 - 用于自定义测试
ApplicationContext
的新ContextCustomizer
API在bean定义之后且上下文刷新之前被加载到上下文中。Customizer
可以通过第三方注册,但需要实现自定义的ContextLoader
。 -
@Sql
和@SqlGroup
现在可作为元注解,用来创造组合注解并可重写其属性。 -
ReflectionTestUtils
在当set或get一个字段时,会自动解除代理。 - 服务器端的SpringMVC测试支持响应头带有多个值。
- 服务器端的SpringMVC测试解析表单数据请求内容并填充请求参数。
- 服务器端的SpringMVC测试支持对已调用的处理器方法模拟断言。
- 客户端的REST测试允许指明希望发送多少次请求并决定是否请求的顺序可被忽略。
- 客户端的REST测试支持在请求体中添加表单数据。
6.8 支持新库和服务器
- Hibernate ORM 5.2(仍然能很好地支持4.2/4.3和5.0/5.1,但是3.6已经过时了)
- Jackson 2.8(至少需要2.6以上版本)
- OkHttp 3.x(同时仍然支持OkHttp 2.x)
- Tomcat 8.5.2 及 9.0 里程碑版
- Netty 4.1
- Undertow 1.4
- WildFly 10.1
另外,spring 4.3的spring-core.jar中集成了更新的ASM 5.1, CGLIB 3.2.4和Objenesis 2.4。