Spring Framework 6.1 正式发布
Spring Framework 6.1 中的新变化
核心容器
- 总体上 与虚拟线程和 JDK 21 兼容。
- 虚拟线程的配置选项:专用的
VirtualThreadTaskExecutor
和SimpleAsyncTaskExecutor
上的虚拟线程模式,以及具有新线程每个任务策略和虚拟线程模式的类似的SimpleAsyncTaskScheduler
。 - 与 Project CRaC(JVM 检查点恢复)的生命周期集成(请参阅 相关文档)),包括
-Dspring.context.checkpoint=onRefresh
选项。 - 为
ThreadPoolTaskExecutor
和ThreadPoolTaskScheduler
以及SimpleAsyncTaskScheduler
集成了生命周期 暂停/恢复功能 和 并行优雅停机 功能。 - 可使用
-Dspring.context.exit=onRefresh
选项进行 AppCDS 训练运行,这是主要的用例;请参阅 31595。 - 可达性元数据贡献改进,为即将到来的 GraalVM 变动做准备:缺失的可达性元数据将很快报告为运行时异常,以获得更好的开发人员体验。参见 31213。
- 异步/响应式销毁方法(如 R2DBC
ConnectionFactory
);参见 26691。 - 异步/响应式 Cacheable 方法,包括缓存接口和
CaffeineCacheManager
中的相应支持;参见 17559 和 17920。 - 响应式
@Scheduled
方法(包括 Kotlin 正则表达式);参见 22924。 - 为每个
@Scheduled
方法选择特定目标调度器;见 20818。 - 用于一次性任务(仅有初始延迟)的
@Scheduled
方法;见 31211。 @Scheduled
方法的可观测性;见 29883。- Spring 不会为
@Async
或@EventListener
注解的方法生成开箱即用的观测结果,但会帮助你为这些方法的执行传播上下文(例如带有当前 trace id 的 MDC 日志)。请参见新的ContextPropagatingTaskDecorator
、相关参考文档部分 和 issue 31130。 Validator
工厂方法,用于编程式 validator 实现;请参阅 29890。Validator.validateObject(Object)
返回Errors
和Errors.failOnError
方法,可灵活用于编程;参见 19877。MethodValidationInterceptor
抛出MethodValidationException
异常的子类ConstraintViolationException
,其中的违反约束已适配为MessageSource
可解析的代码,并且对于带有级联违规的@Valid
参数,适配为Errors
实例。请参阅 29825 和总体 issue 30645。- 支持
@PropertySource
中的资源模式;参见 21325。 - 在
BeanWrapper
和DirectFieldAccessor
中支持Iterable
和MultiValueMap
绑定;请参阅 907 和 26297。 - 修订了
Instant
和Duration
解析(与 Spring Boot 一致);见 22013。 - 支持在 SpEL 表达式的属性/字段/变量名中使用 A-Z 以外的字母;参见 30580。
- 支持将
MethodHandle
注册为 SpEL 函数(请参阅 相关文档)。 - Spring AOP 现在支持 Coroutines;参见 22462。
数据访问和事务处理
- 通用的
TransactionExecutionListener
,具有由事务管理器触发的 before/afterBegin、before/afterCommit 和 before/afterRollback 回调(适用于线程绑定事务和响应式事务);参见 27479。 @TransactionalEventListener
和TransactionalApplicationListener
始终在原始线程中运行,与异步多线程设置无关;参见 30244。- 当
ApplicationEvent
以事务上下文作为事件源发布时,@TransactionalEventListener
和TransactionalApplicationListener
可以参与响应式事务;请参阅 27515。 CompletableFuture
失败会触发异步事务方法的回滚;请参阅 30018。DataAccessUtils
提供了多种具有java.util.Optional
返回类型的optionalResult
方法;请参阅 27735。- 新的
JdbcClient
在JdbcTemplate
和NamedParameterJdbcTemplate
的基础上为查询/更新语句提供了统一的界面,具有灵活的参数选项和灵活的结果检索选项;请参阅 30931。 SimplePropertyRowMapper
和SimplePropertySqlParameterSource
策略可与JdbcTemplate
/NamedParameterJdbcTemplate
以及JdbcClient
一起使用,为结果对象和命名参数持有者提供灵活的构造函数/属性/字段映射;参见 26594。SQLExceptionSubclassTranslator
可通过覆盖的customTranslator
进行配置;请参阅 24634。- R2DBC
DatabaseClient
提供的bindValues(Map)
和bindProperties(Object)
分别用于预先组成的参数值 map 和基于 bean 属性或 record 组件的参数对象,请参见 27282。 - R2DBC
DatabaseClient
为普通数据库列值提供mapValue(Class)
,为基于 bean 属性或 record 组件的结果对象提供mapProperties(Class)
;请参阅 26021。 BeanPropertyRowMapper
和DataClassRowMapper
也可用于 R2DBC;请参阅 30530。- 使用
HibernateJpaDialect
的JpaTransactionManager
尽可能将 Hibernate 提交/回滚异常转换为DataAccessException
子类,例如转换为CannotAcquireLockException
,与 Repository 操作的持久化异常转换抛出的异常层次结构保持一致。主要动机参见 31274: PostgreSQL 序列化失败。
Web 应用
- Spring MVC 和 WebFlux 现在已为带有
@Constraint
注解的 Controller 方法参数提供内置方法验证支持。这意味着不再需要在 Controller 类级别使用@Validated
来通过 AOP 代理启用方法验证。内置方法验证是在现有的 Model Attribute 和请求体参数验证基础上分层进行的。两者的集成和协调更加紧密,例如避免了重复验证的情况。迁移详情请参阅 升级至 6.1,所有相关任务和反馈请参阅总括 issue 30645。 - 方法验证支持对方法参数进行验证,这些参数可以是对象的集合、数组或 Map。
- 新的内置方法验证引发的
HandlerMethodValidationException
公开了一个Visitor
API,用于按 Controller 方法参数类型(如 @RequestParameter
、@PathVariable
等)处理验证错误。 MethodValidationInterceptor
支持Mono
和Flux
方法参数的验证,请参见 issue 20781。- 如果没有匹配的 Handler,Spring MVC 默认会抛出
NoHandlerFoundException
;如果没有匹配的静态资源,Spring MVC 默认会抛出ResponseStatusException(NOT_FOUND)
。参见 29491。 - ErrorResponse 允许通过
MessageSource
自定义ProblemDetail
类型,并通过其 Builder 使用自定义ProblemDetail
。 - Spring MVC 在处理错误和渲染错误响应之前重置 Servlet response buffer。
DataBinder
现在支持 构造函数绑定,其中参数值通过NameResolver
(例如在 HTTP 请求参数 Map 中)进行查找,这些查找可通过@BindParam
注解进行自定义。通过调用初始化构造器参数所需的构造器,这也支持嵌套对象结构。该功能已集成到 Spring MVC 和WebFlux
的数据绑定(Data Binding)中,并为仅预期参数的数据绑定提供了更安全的选择,更多详情请参见 Model 设计。Spring MVC 和 WebFlux 现在支持通过构造函数进行数据绑定,包括嵌套对象构造函数- WebFlux 提供了在不同
Executor
(如VirtualThreadTaskExecutor
)上阻塞执行具有同步签名的 Controller 方法的选项,请参阅参考文档中的 阻塞执行。 SseEmitter
现在可根据 SSE 格式在数据格式中加入换行符。- 新的
RestClient
,一种同步 HTTP 客户端,提供与WebClient
类似的 API,但与RestTemplate
共享基础结构。请参见 29552。 - 基于 Jetty 的
ClientHttpRequestFactory
,与RestTemplate
和RestClient
搭配使用;参见 30564。 - 与
RestTemplate
和RestClient
一起使用的基于 JDKHttpClient
的ClientHttpRequestFactory
;请参阅 30478。 - 基于 Reactor Netty 的
ClientHttpRequestFactory
,可与RestTemplate
和RestClient
配合使用;参见 30835。 - 改进了各种
ClientHttpRequestFactory
实现中的缓冲;请参阅 30557。 - 除了现有的响应式
WebClient
Adapter 外,HTTP 接口客户端 还为新的RestClient
和RestTemplate
提供了内置 Adapter。 - HTTP 接口客户端支持将
MultipartFile
作为输入方法参数。 - HTTP 接口客户端支持将
UriBuilderFactory
作为输入方法参数使用,而不是底层配置的参数,例如在必要时动态更改 baseURL。 - HTTP 接口方法上使用的
@HttpExchange
注解现在支持在 Spring MVC 和 WebFlux 中进行服务器端处理,以替代@RequestMapping
,更多详情和指导请参阅@HttpExchange
。 - 为基于 Reactor Netty 的
ClientHttpRequestFactory
(与RestTemplate
和RestClient
搭配使用)和ClientHttpConnector
(与WebClient
搭配使用)添加了 JVM 检查点恢复支持;请参阅 31280、31281 和 31180。 - 在 WebFlux 中对协程(Coroutines)的支持进行了修订,包括 在
CoWebFilter
中的CoroutineContext
传播,带 Filter 的 coRouter DSL 中的CoroutineContext
传播,coRouter DSL 中的新的context
函数,对 WebFlux 中的@ModelAttribute
与挂起函数的支持,以及 一致使用awaitSingle()
的Mono
变体。
MQ 应用
- STOMP 支持一个新的
preserveReceiveOrder
配置选项,用于有序处理从给定客户端收到的消息。这是现有的保留发布顺序(preservePublishOrder
)标志之外的另一个选项,用于向客户端发布消息。请参阅参考文档中的 消息顺序 部分。 - 作为
@MessageMapping
的替代方法,RSocket 接口方法上使用的@RSocketExchange
注解现在支持响应方处理,更多详情和指导请参阅 @RSocketExchange。 - I消息 Handler 方法也会检测到接口参数注解(类似于网 Web Handler 方法)。
- WebSocket 中基于 SpEL 的
selector
Header 支持现在默认为禁用,必须显式启用。有关迁移的详细信息,请参阅 30550 和 升级到 6.1。 - JMS 的可观测性支持。现在,当使用
JmsTemplate
发布消息以及使用MessageListener
或@JmsListener
处理消息时,都会生成观测结果。请参见参考文档部分和 issue 30335。
测试
- 支持
ApplicationContext
失败阈值:避免重复尝试在TestContext
框架中加载失败的ApplicationContext
,失败阈值默认为 1,但可通过系统属性进行配置(请参阅 相关文档)。 - 支持使用
@RecordApplicationEvents
记录异步事件。参见 30020。- 记录来自主测试线程以外线程的事件。
- 从单独的线程断言事件 - 例如使用 Awaitility。
- MockMvc 现在支持使用 init 参数初始化 Filter,并支持映射到特定的 Dispatch Type。
MockMvcWebTestClient
现在支持RequestPostProcessor
Hook,例如允许在不同测试中使用不同的用户身份。请参见 31298。- 除了
RestTemplate
之外,MockRestServiceServer
还支持新的RestClient
。 - 在
MockHttpServletResponse.setCharacterEncoding()
中支持null
。参见 30341。
Spring Framework 6.0 中的新变化
JDK 17+ 和 Jakarta EE 9+ 基线
- 现在,整个框架代码库都基于 Java 17 源代码级别。
- 将
Servlet
、JPA
等的命名空间从javax
迁移到jakarta
。 - 运行时兼容 Jakarta EE 9 和 Jakarta EE 10 API。
- 与最新的 Web 服务器兼容:Tomcat 10.1、Jetty 11 和 Undertow 2.3。
- 与 虚拟线程 的早期兼容性(JDK 19 的预览版)。
一般核心修订
- 升级至 ASM 9.4 和 Kotlin 1.7。
- 完整的 CGLIB fork,支持捕获 CGLIB 生成的类。
- 为 AOT 转换 奠定全面基础。
- 对 GraalVM 原生镜像的一流支持(请参阅 相关的 Spring Boot 3 博客)。
核心容器
- 基本 bean property 判断,默认情况下不使用
java.beans.Introspector
。 - 在
GenericApplicationContext
中支持 AOT 处理(refreshForAotProcessing
)。 - 基于预解析构造函数和工厂方法的 Bean 定义转换。
- 支持 AOP 代理和配置类的早期代理类确定。
PathMatchingResourcePatternResolver
使用 NIO 和模块路径 API 进行扫描,分别支持 GraalVM 原生镜像和 Java 模块路径内的 classpath 扫描。DefaultFormattingConversionService
支持基于 ISO 的默认java.time
类型解析。
数据访问和事务处理
- 支持预先确定 JPA Manager 类型(以便纳入 AOT 处理)。
- JPA 支持 Hibernate ORM 6.1(保留与 Hibernate ORM 5.6 的兼容性)。
- 升级到 R2DBC 1.0(包括 R2DBC 事务定义)。
- 对齐 JDBC、R2DBC、JPA 和 Hibernate 之间的数据访问异常翻译。
- 取消 JCA CCI 支持。
Spring Messaging
- 基于
@RSocketExchange
服务接口的 RSocket 接口客户端。 - 基于 Netty 5 alpha 的 Reactor Netty 2 早期支持。
- 支持 Jakarta WebSocket 2.1 及其标准 WebSocket 协议升级机制。
一般 Web 修订
- 基于
@HttpExchange
service 接口的 HTTP 接口客户端。 - 支持 RFC 7807 问题细节。
- 统一 HTTP 状态码处理。
- 支持 Jackson 2.14。
- 与 Servlet 6.0 保持一致(同时保留与 Servlet 5.0 的运行时兼容性)。
Spring MVC
- 默认使用
PathPatternParser
(可选择使用PathMatcher
)。 - 删除过时的 Tiles 和 FreeMarker JSP 支持。
Spring WebFlux
- 新的
PartEvent
API,用于 multipart form 上传流(客户端 和 服务器)。 - 新的
ResponseEntityExceptionHandler
可自定义 WebFlux 异常并渲染 RFC 7807 错误响应。 - 非流媒体类型的
Flux
返回值(写入前不再收集到List
中)。 - 基于 Netty 5 alpha 的 Reactor Netty 2 早期支持
- 与
WebClient
集成的 JDKHttpClient
。
可观测性
在 Spring 框架的多个部分中使用 Micrometer Observation 直接实现可观测性。spring-web 模块现在需要 io.micrometer:micrometer-observation:1.10+
作为 compile
依赖。
RestTemplate
和WebClient
可用于生成 HTTP 客户端请求观测结果。- 可以使用新的
org.springframework.web.filter.ServerHttpObservationFilter
对 Spring MVC 进行 HTTP 服务器观测。 - Spring WebFlux 可使用新的
org.springframework.web.filter.reactive.ServerHttpObservationFilter
进行 HTTP 服务器观测。 - 集成 Micrometer 上下文传播 功能,用于从 Controller 方法中获取
Flux
和Mono
返回值。
测试
- 支持在 JVM 上或 GraalVM 原生镜像中测试 AOT 处理的 Application Context。
- 集成 HtmlUnit 2.64+ 请求参数处理功能。
- Servlet Mck(
MockHttpServletRequest
、MockHttpSession
)现在基于 Servlet API 6.0。 - 新增
MockHttpServletRequestBuilder.setRemoteAddress()
方法。 - JUnit 4 和 TestNG 的四个抽象基本测试类不再通过
@TestExecutionListeners
声明监听器,而是依赖于默认监听器的注册。
Ref:https://github.com/spring-projects/spring-framework/wiki/What's-New-in-Spring-Framework-6.x