更新时间:2026 年 8 月。本文以 spring boot 3.5 与 spring boot 4.x 为主要对比对象。spring boot 3 是一个持续演进的大版本,3.0 与 3.5 的能力并不完全相同,因此下文会特别区分“4.x 新增”和“3.x 后期已经具备”的功能。
spring boot 4 已经进入稳定版本阶段。很多开发者看到大版本号后,第一反应是:“是不是必须升级 java 21?”“javax 又要迁一次吗?”“原来的 starter 还能不能用?”
先给出结论:spring boot 4 的核心变化不是 java 版本,而是 spring framework 7、jakarta ee 11、模块拆分以及一批依赖和 api 的代际升级。 它仍然以 java 17 为最低基线,但应用的依赖结构、web 容器、json 处理和空值语义都会受到影响。
一、核心差异速览
| 对比项 | spring boot 3.x | spring boot 4.x |
|---|---|---|
| 最低 java 版本 | java 17 | java 17 |
| spring framework | 6.x | 7.x |
| jakarta ee | 10 | 11 |
| servlet api | 6.0 | 6.1 |
| 默认嵌入式 tomcat | 10.1.x | 11.0.x |
| jetty | 12.0.x(不同 3.x 小版本有差异) | 12.1.x |
| json 主线 | jackson 2 | jackson 3 |
| 模块组织 | 相对集中 | starter 与自动配置进一步细分 |
| 空值注解 | spring 自有注解为主 | jspecify 语义全面强化 |
| 原生镜像 | 已支持 aot / graalvm | 继续增强,4.0 文档要求 graalvm 25+ |
官方当前的 spring boot 4.0.7 系统要求显示:最低 java 版本仍是 17,可运行到 java 26;maven 需要 3.6.3 或更高版本,gradle 支持 8.14+ 和 9.x。也就是说,“spring boot 4 强制 java 21”是一个常见误解。生产项目可以优先选择 java 21 或更新的 lts,但这属于工程选型,而不是框架最低门槛。
二、底层升级到 spring framework 7
spring boot 4 最重要的变化,是底层从 spring framework 6 升级到 spring framework 7。
1. jspecify 空值语义
spring framework 7 使用 jspecify 注解表达空值约束。对于 java 项目,ide 和静态分析工具可以更准确地识别“默认非空”和“允许为空”;对于 kotlin 项目,平台类型会减少,调用 spring api 时的空安全提示也更明确。
import org.jspecify.annotations.nullable;
public @nullable string findnickname(long userid) {
return repository.findnickname(userid).orelse(null);
}
迁移时需要关注两类问题:一是重写框架接口后出现的空值签名告警;二是 kotlin 代码中原本宽松的平台类型被识别为严格的可空或非空类型。
2. http api 版本控制
spring framework 7 为 web mvc 和 webflux 增强了 api 版本控制能力。相比在每个 controller 中手工读取请求头或拼接 url,框架层可以统一解析版本,并将版本规则应用到请求映射。
@restcontroller
@requestmapping("/orders")
class ordercontroller {
@getmapping(value = "/{id}", version = "1.0")
orderv1 detailv1(@pathvariable long id) {
return orderservice.findv1(id);
}
@getmapping(value = "/{id}", version = "2.0")
orderv2 detailv2(@pathvariable long id) {
return orderservice.findv2(id);
}
}
具体版本来源可以按照项目规范配置为请求头、查询参数或媒体类型参数。对于正在维护多代开放 api 的团队,这是 boot 4 技术栈里很实用的一项变化。
三、jakarta ee 11 与 web 容器升级
spring boot 3 已经完成了从 javax.* 到 jakarta.* 的大迁移,因此从 boot 3 升到 boot 4 时,不会再经历一次命名空间整体替换。真正需要处理的是 jakarta ee 10 到 11 的规范升级。
boot 4 使用 servlet 6.1,对应的默认容器也升级到了 tomcat 11;jetty 则进入 12.1 代。影响通常集中在以下位置:
- 自定义 filter、servlet、listener 和容器定制代码;
- 直接依赖 servlet api 或容器内部类的组件;
- 与旧版 tomcat、jetty 强耦合的监控、网关或安全插件;
- 尚未适配 jakarta ee 11 的第三方 starter。
如果项目只是使用标准的 spring-boot-starter-web 和普通 controller,改动往往不大;如果项目有大量容器扩展代码,就应该先建立兼容性清单。
四、jackson 3:最容易被低估的迁移点
spring boot 4 的 json 主线升级到 jackson 3。它不只是把版本号从 2 改成 3,部分包名、模块和 api 也发生了变化。业务代码若直接操作 objectmapper、注册 module、编写自定义序列化器,或者依赖 jackson 2 专用扩展,都需要重点检查。
典型排查命令:
# 在项目中搜索直接使用 jackson api 的位置 rg "com\.fasterxml\.jackson|objectmapper|jsonserializer|jsondeserializer" src
迁移建议:
- 先确认 spring boot 自动配置能否满足需求,减少手工创建
objectmapper; - 检查日期时间、枚举、bigdecimal、多态类型和未知字段策略;
- 对请求与响应 json 做契约回归测试,而不是只验证项目能编译;
- 检查 openapi、消息队列 sdk、数据库 json 类型等外围组件对 jackson 3 的兼容情况。
五、starter 与自动配置更加模块化
spring boot 4 对代码库进行了更细粒度的模块化。许多原来集中在大模块中的自动配置被拆分,web mvc、webflux、jackson、测试支持等方向都有更明确的模块边界。
这项变化的好处是依赖关系更清晰、按需引入更容易、原生镜像和启动分析也更精确;代价是升级时不能只改父版本号,还要检查依赖树。
# maven mvn dependency:tree # gradle ./gradlew dependencies
尤其要留意:
- 以前被“顺带传递进来”的类是否还在 classpath;
- 自定义 starter 是否依赖了 boot 内部实现;
- 测试代码是否需要更具体的测试 starter;
- 自动配置类的包名和注册方式是否发生变化。
原则上,业务项目应该依赖公开 starter 和公开 api,避免直接依赖 spring-boot-autoconfigure 内部类。这样迁移成本会明显降低。
六、哪些能力并不是 boot 4 才有?
网上不少对比文章把虚拟线程、结构化日志、restclient、声明式 http interface 都归为 spring boot 4 新功能,这并不准确。
1. 虚拟线程
spring boot 3.2 已经支持虚拟线程,java 21 环境中可以启用:
spring:
threads:
virtual:
enabled: trueboot 4 延续并完善这项能力,但它不是 4.0 首次出现。启用后仍需排查线程局部变量、同步锁、连接池和会造成线程固定的平台调用。
2. 结构化日志
spring boot 3.4 已经提供结构化日志支持,可输出 ecs、gelf 或 logstash 格式。boot 4 在新的依赖基线上继续演进,但“支持 json 日志”本身不能算 4.x 独占特性。
logging:
structured:
format:
console: ecs3. restclient 与 http interface
restclient 和声明式 http interface 在 spring framework 6.x 时代已经出现。framework 7 的重点是继续增强,例如与 api 版本控制、客户端注册和配置体系更好地结合。
七、aot 与 graalvm 原生镜像
spring boot 3 已经具备成熟的 aot 处理和 graalvm native image 支持。boot 4 继续扩大运行时提示覆盖范围,并适配新一代 graalvm。官方 4.0.7 文档给出的基线是 graalvm 25 及以上。
# maven 项目构建原生镜像 mvn -pnative native:compile # gradle 项目构建原生镜像 ./gradlew nativecompile
升级时,反射、动态代理、资源文件、序列化和 jni 仍然是原生镜像验证重点。jvm 模式启动成功,并不代表 native image 一定能构建或正常运行。
八、推荐的迁移路线
第一步:先升级到最新的 spring boot 3.5.x
不要直接从 3.0、3.1 跳到 4.x。先升级到 3.5.x,处理所有弃用警告,并让测试稳定通过。boot 4 会删除一批在 3.x 中已经标记为废弃的 api。
第二步:升级构建环境
- jdk 最低 17,生产环境建议结合团队周期选择合适的 lts;
- maven 使用官方支持版本;
- gradle 升级到 boot 4 支持的 8.14+ 或 9.x;
- 更新编译、测试、覆盖率、代码生成和容器镜像插件。
第三步:检查依赖兼容矩阵
重点检查 spring cloud、spring security 扩展、mybatis、数据库驱动、消息队列、注册中心、api 文档和公司内部 starter。大版本升级中,第三方依赖通常比业务 controller 更容易成为阻塞点。
第四步:切换 boot 4 并引入属性迁移器
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-properties-migrator</artifactid>
<scope>runtime</scope>
</dependency>它会在启动时分析被重命名或删除的配置属性。修复完成后应移除此依赖,避免长期保留临时迁移逻辑。
第五步:分层验证
建议至少完成以下验证:
- 编译与单元测试;
applicationcontext启动测试;- http 接口契约与 json 序列化回归;
- 数据库、缓存、消息队列和外部服务集成测试;
- 可观测性验证,包括日志、指标和链路追踪;
- 若使用原生镜像,再单独执行 native image 构建与冒烟测试。
九、该不该立刻升级?
适合升级的情况:
- 新项目,希望直接使用 spring framework 7 和 jakarta ee 11;
- 依赖组件已经明确支持 boot 4;
- 团队需要 jackson 3、api 版本控制或更细粒度模块化;
- 已有完整的自动化测试与灰度发布能力。
建议先评估再升级的情况:
- 项目依赖大量内部 starter 或旧版中间件;
- 直接使用了较多 jackson 2、容器内部类或 boot 内部 api;
- spring cloud 等配套版本尚未完成兼容验证;
- 项目缺少接口契约测试和回滚机制。
总结
spring boot 3 到 4 的升级,可以概括为四句话:
- java 最低版本仍是 17,java 21 并非强制要求;
- 核心底座升级为 spring framework 7、jakarta ee 11 和 servlet 6.1;
- jackson 3、模块拆分和废弃 api 清理是迁移中的主要工作量;
- 虚拟线程、结构化日志、restclient 等能力在 boot 3 后期已经存在,不应被误认为 4.x 独占。
真正稳妥的升级方式,不是修改一个版本号后反复解决编译错误,而是先站稳 3.5.x,建立依赖兼容矩阵,再按照“构建、启动、契约、集成、可观测性、原生镜像”的顺序逐层验证。
如果你正在做真实项目迁移,建议把当前 boot 版本、jdk 版本、spring cloud 版本和关键中间件列成表格,再逐项确认兼容性。这样通常比“边升级边踩坑”更省时间。
以上就是springboot 3到4的升级重点与迁移路线的详细内容,更多关于springboot 3到4升级与迁移的资料请关注代码网其它相关文章!
发表评论