Spring Boot 4 迁移:先过依赖底线,再谈新特性

2026-09-24 Aryee 1

Spring Framework 7.0.0 在 2025 年 11 月 13 日发布,Spring Boot 4.0.0 一周后的 11 月 20 日跟上。到现在已经有若干维护版本,是可以正经讨论迁移的时点了。

先说结论:这次升级的难度不在新特性,在一堆改名和删除。它们不会让代码写不出来,但会让构建在半途崩掉、或者启动时缺一整类自动配置。所以下面按「编译期能暴露」和「跑起来才暴露」两类分开列——这个分法决定了你能不能在 CI 里就把活干完。

依赖底线:比传闻中宽松

很多人以为 Boot 4 抬了 Java 门槛,其实没有。官方口径是 Framework 7 保留 JDK 17 基线,同时推荐 JDK 25 作为最新 LTS。Boot 侧的系统要求页面写得更具体:

项 要求
Java 17 最低,官方说明支持到 Java 26
Spring Framework 7.0 这一档的较新维护版(Boot 的系统要求页给了最低值)
Jakarta EE 11 基线
Servlet 容器 Servlet 6.1+(Tomcat 11.0.x / Jetty 12.1.x)

表里没列的几格——Maven、Gradle、GraalVM、Kotlin 的最低版本——每出一个维护版都可能往上抬一档,动手前用你自己那套构建工具链实测一次,别照抄任何一篇文章里的数字。

真正会挡路的是 Jakarta EE 11 和 Servlet 6.1:内嵌容器要跟着换版本,而 Servlet 容器之外的东西——安全框架的 Filter 链、老的监控探针、任何直接实现 javax.servlet 类型的组件——都得确认是否已经有 jakarta.servlet 版本。如果你的技术栈里还有 Spring Security 5 时代的东西或者第三方 servlet filter,这一项的优先级高于 Boot 本身。

编译期就能暴露的改动

一、starter 改名:构建阶段第一道坎

Boot 4 把一批 starter 换成了更规范的名字:

旧 新
spring-boot-starter-web spring-boot-starter-webmvc
spring-boot-starter-oauth2-client spring-boot-starter-security-oauth2-client
spring-boot-starter-oauth2-resource-server spring-boot-starter-security-oauth2-resource-server
spring-boot-starter-oauth2-authorization-server spring-boot-starter-security-oauth2-authorization-server
spring-boot-starter-web-services spring-boot-starter-webservices

WebFlux 也拿到了自己的专用 starter。

这件事的麻烦不在改名本身,在于旧名字不会给你一条清晰的报错——依赖解析不到,构建失败,但错误信息指向的是坐标而不是「你该换成哪个」。所以正确做法是先在依赖树里把 spring-boot-starter- 开头的项全部导出来,逐个对照,而不是等 Maven 一条条报。

顺带一个删除项:内嵌的 launch script 支持被移除了(就是 spring-boot-starter-parent 里那套把 jar 直接当可执行 shell 脚本跑、省掉 java -jar 的封装)。如果你的部署方式走的正是那条路,这一项要提前确认,改法无非是回到 java -jar 或者自己出一版启动脚本。

二、Jackson 3:包名变了,这才是最大的工程量

Framework 7 / Boot 4 把 Jackson 3 作为默认,而 Jackson 3 换了 Maven 坐标和 Java 包名:从 com.fasterxml.jackson 变成 tools.jackson。

这意味着所有 import 都要改,包括那些写了 TypeReference、ObjectMapper、注解的类。代码量大一点的项目,这一步的 diff 会比整个升级剩下的部分加起来都大。

几处可以少改点:

  • com.fasterxml.jackson.annotation 这一组的包名没变,注解类不用动。
  • Jackson 2 仍然支持,但要显式引 spring-boot-jackson2 模块。 这是这次迁移里最有价值的一条退路:如果你的依赖树里有某个库死咬 Jackson 2(老版 SDK、某些序列化组件),不必强推它升级,可以让 Jackson 2 和新默认并存一阵。
  • Boot 侧的 @JsonComponent 改名为 @JacksonComponent。这类自己写的定制组件容易漏,因为它们不在依赖里、只在源码里。

我的建议顺序:先把 Jackson 2 与 3 并存的边界画出来,再动手改 import。反过来做的话,中途一定会碰到「这个库不支持 Jackson 3」,此时已经改了一半,退回去的成本比当初多引一个模块高得多。

三、测试与注解层的替换

  • @MockBean / @SpyBean → @MockitoBean / @MockitoSpyBean,包路径也换了。测试基类里写了这两个注解的,全项目替换即可,但注意新注解的作用域语义有调整(旧的那个是类级别注册,新的要留意重复声明的行为),别只做完文本替换就认为等价。
  • Spock 支持被移除。 还在用 Groovy + Spock 写集成测试的团队,这一项是选择题而不是改造题:迁到 JUnit,或者停在 Boot 3 上不动。

跑起来才暴露的改动

这几条最危险,因为它们不影响编译。

一、Actuator 的存活与就绪探针默认开启。 这在 Kubernetes 上是好事,但它的另一面是:端口上的探测端点从「你不配就没有」变成了「默认就在那儿」。如果服务在集群外可路由、或者运维网络策略是按「这些路径不存在」的前提配的,升级等于悄悄新增了一个公开端点。升级前先确认 8081(或你合并到主端口的那个 actuator 端口)的实际暴露面。

二、EnvironmentPostProcessor 换了包,到 org.springframework.boot。 这是 SPI:靠 spring.factories / AutoConfiguration.imports 注册的实现类,包名写错不会编译失败,只会静默不生效。自定义过配置加载逻辑的项目,要显式验一次它有没有被调用——最直接的方式是在里面打一条日志并确认它出现在启动输出里。

三、MongoDB 配置项前缀改成 spring.mongodb.*。 属性改名是「删掉不报错、写错不报错」的一类,只在连不上时才发现。凡是自管配置中心里存了这些 key 的(而不是写在 application.yml 里能靠 IDE 补全看出问题的),要单独在配置中心做一次全量搜索。

四、JPA 静态元模型生成器换成 hibernate-processor。 构建插件里引的 hibernate-jpamodelgen 要换掉,否则 JMetaModel 不再生成,运行期 Criteria 查询报的是「找不到静态元模型属性」这类间接错误。

值得主动用的两条

  • HTTP 接口客户端(HTTP Service Interfaces):Framework 7 对「声明式 HTTP 接口 + 多个目标主机」的配置做了专门支持。如果你手上还有一堆手写 WebClient 调用外部服务的代码,这一块可以省掉不少样板,同时把超时、重试的位置统一起来。
  • org.springframework.core.retry 的重试支持:框架层有了基础重试抽象,不必为了三次重试再引一个第三方库。

需要说明一点:网上流传的「Boot 4 强制要求编译加 -parameters」「@ConstructorBinding 已移除」这两条,迁移指南和系统要求页上都没有这两条的对应表述,所以按未证实处理。判断依据仍以官方迁移指南为准。

一条迁移顺序

  1. 先在 Boot 3.x 上把废弃 API 清零。 这一步单独做,做完能跑、能回退。它能把后面所有报错的范围缩小到「Boot 4 独有的问题」。
  2. 画 Jackson 边界:列出依赖树里所有会拉进 Jackson 2 的项,逐个确认有没有 Jackson 3 兼容版本。这一步的产出一份清单,不产代码。
  3. 换构建坐标 + 改 import,让项目能编译。这一步 diff 最大,也最容易评审疲劳——所以要单独一个 PR,不要混任何业务改动。
  4. 容器与 Servlet 层验证:Tomcat 11 / Jetty 12.1 起一遍,重点看 filter、listener 和会话相关行为。
  5. 专门过一遍上面那四条「跑起来才暴露」的,尤其是 SPI 与配置中心里的 key。

第 3 步和第 5 步之间留几天,不要连着做。这个升级里最难查的问题,都发生在「编译过了、启动也正常、但某个静默失效的组件第一次被调用」的时刻。

你手上那套系统,卡在哪一步?

留个手机号和方便的时间,我打过来先听你说现状与约束,再给可执行的判断:这套系统是该继续修、该动哪里,还是干脆重做一版设计更省。

约一次沟通不接纯 UI 外包,只做系统层面的问题。