Spring 6.0发布:重大升级与迁移指南 - 详解
以下内容是 Spring Framework 6.0 的官方发布说明(Release Notes),由 Brian Clozel 在 2024 年 10 月 28 日编辑。这份文档非常关键,因为它标志着 Spring 框架的一次重大版本升级,从 Spring 5 到 Spring 6 是一次不兼容的升级(breaking change)。
下面我将为你逐部分解析这份 Release Notes 的核心信息,并解释它的实际影响和开发者应该如何理解和应对。
总体概览
| 项目 | 内容 |
|---|---|
| 发布时间 | 2024年10月28日 |
| 最低 Java 版本 | Java 17+(不再支持 Java 8/11) |
| 技术栈迁移 | 从 javax.* → jakarta.*(Jakarta EE 9+) |
| 主要目标 | 支持云原生、GraalVM 原生镜像、AOT 编译、虚拟线程等现代技术 |
✅ 这意味着:如果你还在用 Java 8 或 Spring 5.x,要升级到 Spring 6 必须先升级 JDK 和所有依赖库。
一、基础升级(Baseline Upgrades)
1. Java 17+ 要求
- 所有代码基于 Java 17 编写。
- 支持 虚拟线程(Virtual Threads)(JDK 19+ 预览功能,未来会成为核心特性)。
- 不再支持 Java 8、11、16 等旧版本。
提示:Spring Boot 3 也基于 Spring 6,所以 Spring Boot 3 要求 Java 17+。
2. Jakarta EE 9+ 迁移
- 所有包名从
javax.*改为jakarta.*javax.servlet→jakarta.servletjavax.persistence→jakarta.persistencejavax.validation→jakarta.validationjavax.inject→jakarta.inject
- 第三方组件也要升级:
- Hibernate ORM 5.6+(
hibernate-core-jakarta)或直接上 Hibernate 6.1+ - Tomcat 10+ / Jetty 11+ / Undertow 2.2.19+
- EclipseLink 3.0+
- Hibernate ORM 5.6+(
⚠️ 如果你的项目还在用
javax.servlet.*,必须全部替换为jakarta.servlet.*,否则编译失败!
️ 二、被移除的功能(Removed APIs)
这些功能已被永久删除,不能再使用:
| 被移除功能 | 替代方案 |
|---|---|
| Hessian、HTTP Invoker、JMS Invoker、JAX-WS | 已废弃多年,建议使用 REST 或 gRPC |
| EJB 访问支持 | 使用 JNDI 直接查找(JndiObjectFactoryBean) |
org.springframework.cache.ehcache(Ehcache 2.x) | 升级到 Ehcache 3.x 或使用 JCache API(javax.cache) |
❗ 特别注意:Ehcache 2.x 即将停止维护,必须迁移!
三、核心容器(Core Container)
1. Bean 属性探测机制变更
- 默认不再使用
java.beans.Introspector(性能更好) - 如果旧代码依赖复杂 JavaBeans 行为,可通过配置恢复:
# META-INF/spring.factories
org.springframework.beans.BeanInfoFactory=org.springframework.beans.ExtendedBeanInfoFactory
2. 参数名推断警告
LocalVariableTableParameterNameDiscoverer已弃用,会打印警告。- 解决方法:编译时加上
-parameters参数(Java 8+):
javac -parameters MyClass.java
- Kotlin 用户建议加
-java-parameters编译选项。
3. @Inject, @PostConstruct, @PreDestroy 包名变化
- 新位置:
jakarta.inject.Injectjakarta.annotation.PostConstructjakarta.annotation.PreDestroy
- Spring 暂时仍兼容
javax.*版本(用于兼容老 jar 包),但未来可能移除。
4. ListenableFuture 弃用
- 推荐使用
CompletableFuture(Java 8+ 标准异步编程模型)
5. @Async 方法返回类型限制
- 只能返回
void或Future子类(如CompletableFuture) - 其他类型(如
String、Mono)会抛异常。
四、数据访问与事务(Data Access)
1. Hibernate & JPA 升级
- 推荐使用 Hibernate 6.1+(只支持
jakarta.persistence) - Hibernate Validator 7.0+(对应 Jakarta Bean Validation 3.0)
2. JDBC 异常翻译改进
- 默认使用
SQLExceptionSubclassTranslator(更准确) CannotSerializeTransactionException和DeadlockLoserDataAccessException已弃用- 推荐统一使用
PessimisticLockingFailureException或CannotAcquireLockException
3. 移除 JCA CCI 支持
- Java EE 连接器架构(JCA CCI)已过时,被移除。
五、Web 应用(Web Applications)
1. Servlet 容器要求
- 必须使用支持 Jakarta EE 的服务器:
- Tomcat 10.1+
- Jetty 11+
- Undertow 2.3+(注意要用
undertow-servlet-jakarta)
2. 移除过时的集成
| 被移除 | 推荐替代 |
|---|---|
| Apache Commons FileUpload | StandardServletMultipartResolver(基于 Servlet 3.0+) |
| Apache Tiles | 不再推荐,建议用 Thymeleaf、Freemarker 模板引擎 |
| FreeMarker JSP 支持 | 不再支持 JSP,推荐纯模板或前后端分离 |
Spring 6 不再推荐 JSP! 推荐 RESTful 架构或现代前端框架。
3. 尾部斜杠匹配(Trailing Slash Matching)默认关闭
@GetMapping("/some/greeting")
public String greeting() { ... }
- 以前:匹配
/some/greeting和/some/greeting/ - 现在:只匹配
/some/greeting,/some/greeting/返回 404
✅ 解决方案(二选一):
- 显式声明两个路径:
@GetMapping({"/some/greeting", "/some/greeting/"}) - 全局开启兼容模式:
@Configuration public class WebConfig implements WebMvcConfigurer { @Override public void configurePathMatch(PathMatchConfigurer configurer) { configurer.setUseTrailingSlashMatch(true); } }
4. HttpMethod 从 enum 变成 class
- 原因:为了支持自定义 HTTP 方法(如 WebDAV 的
PROPFIND) - 影响:
// 以前 EnumSet<HttpMethod> methods = EnumSet.of(HttpMethod.GET, HttpMethod.POST); // 现在 Set<HttpMethod> methods = Set.of(HttpMethod.GET, HttpMethod.POST); switch语句不能用了,改用if-else
5. RestTemplate 要求 HttpClient 5
- 如果你用了
HttpComponentsClientHttpRequestFactory,必须升级 Apache HttpClient 到 5.x 版本。
6. SourceHttpMessageConverter 不再默认注册
- 如果你用
javax.xml.transform.Source做 XML 处理,需要手动添加:
@Bean
public WebMvcConfigurer webMvcConfigurer() {
return new WebMvcConfigurer() {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(new SourceHttpMessageConverter<>());
// 注意顺序:放在 MappingJackson2HttpMessageConverter 前面
}
};
}
六、新特性与亮点(New and Noteworthy)
1. AOT(Ahead-of-Time)支持 & GraalVM 原生镜像
- Spring 6 为 原生编译 打下基础。
- 支持在 GraalVM 中将 Spring 应用打包成原生可执行文件(启动更快、内存更小)。
GenericApplicationContext.refreshForAotProcessing()可用于预处理 bean 定义。
2. 观测性(Observability)集成 Micrometer
- 内置对 Micrometer Observation 的支持(1.10+)
- 自动追踪:
- HTTP 客户端请求(RestTemplate / WebClient)
- HTTP 服务端请求(MVC / WebFlux)
- Reactor 流上下文传播(Flux/Mono)
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-observation</artifactId>
<version>1.10+</version>
</dependency>
3. 新的声明式 HTTP 客户端
- 类似 Feign,但基于标准:
@HttpExchange(Spring MVC 风格)@RSocketExchange(RSocket 风格)
@HttpExchange(url = "/api/users/{id}")
interface UserClient {
@GetExchange
User getUser(@PathVariable String id);
}
4. Spring MVC 使用 PathPatternParser(默认)
- 更快的路径匹配算法(来自 Spring WebFlux)
- 可选回退到旧的
AntPathMatcher
5. Spring WebFlux 新特性
PartEvent:流式上传 multipart 文件ResponseEntityExceptionHandler:支持返回 RFC 7807 标准错误格式(Problem Details)Flux<T>返回非流式数据时不再自动收集为 List,直接逐个写入响应
七、测试(Testing)
- Servlet Mocks(如
MockHttpServletRequest)基于 Servlet 6.0 API - 测试类路径需包含
jakarta.servlet-api6.0+ - 生产代码仍可用 Servlet 5.0 编译,但测试必须用 6.0+
- 新增
setRemoteAddress()方法用于模拟客户端 IP
✅ 总结:你需要做什么?
| 任务 | 操作 |
|---|---|
| 升级 JDK | 至少 Java 17(推荐 17~21) |
| 迁移到 Jakarta EE | 替换所有 javax.* → jakarta.* 包名 |
| ️ 升级中间件 | Hibernate 6.1 / Tomcat 10.1 / Jetty 11 / HttpClient 5 |
| 移除废弃依赖 | 如 Ehcache 2.x、Commons FileUpload、Tiles |
| ⚙️ 检查编译参数 | 加 -parameters 避免参数名警告 |
| 检查 @Async 方法 | 返回值只能是 void 或 Future |
| 配置尾斜杠行为 | 明确是否开启 setUseTrailingSlashMatch(true) |
| 启用观测性 | 引入 Micrometer 并配置 ServerHttpObservationFilter |
| 考虑 GraalVM | 若追求极致性能,尝试构建原生镜像 |
延伸阅读
- Spring Framework 6 Migration Guide
- Jakarta EE Migration Guide
- Spring Boot 3 Release Notes
- Micrometer Observations
如果你正在计划从 Spring 5.3 升级到 6.0,建议:
- 先升级 JDK 到 17
- 使用工具(如 IDE 或 jdeps)扫描
javax.*依赖 - 逐步替换为
jakarta.* - 更新所有依赖库版本
- 运行测试,修复不兼容问题
需要我帮你生成一个 Spring 5 → Spring 6 的迁移检查清单(Checklist) 吗?

浙公网安备 33010602011771号