《Spring Boot 高级》11.2 依赖与配置迁移清单

把 3.x 到 4.x 的迁移排成有依赖关系的可执行步骤:Java 与构建插件基线、依赖坐标与版本对照、被移除与改名的类与注解、配置属性重命名与移除、spring.factories 到 AutoConfiguration.imports 的沿革,并给出用 unzip 读属性元数据核实的方法。

本节目标:把「从 3.x 迁到 4.x」从一堆零散改动,整理成有先后依赖、可逐条执行、可回退的步骤清单——覆盖 Java 与构建基线、依赖坐标与版本、类与注解改名、配置属性重命名、spring.factories 沿革与测试写法,并给出每一条的核实命令。
适用版本:Spring Boot 4.1.x(Java 21)

11.2 依赖与配置迁移清单

迁移最常见的失败不是「某一项不会改」,而是改的顺序错了。先改 import 再改依赖,编译器会用一屏「找不到符号」淹没你;先改配置属性再改 starter,启动时会因为自动配置没加载而静默失效。所以这一节不按「类型」罗列,而是按依赖关系排成步骤:上一步的产出是下一步的输入。

11.2.1 迁移步骤的依赖关系

先看清整张图的因果关系:

第 0 步  升到最新 3.5.x,清掉所有废弃调用
   │   (不先做这步,4.x 里被移除的废弃 API 会同时爆出来)
   ▼
第 1 步  抬 Java 与构建插件基线(Java 17+/21,Jakarta EE 11)
   │   (不先抬,后面新依赖根本编译不过)
   ▼
第 2 步  依赖坐标与版本(BOM 版本、starter 改名、新增 starter)
   │   (依赖对了,classpath 才稳定,才能判断后续错误)
   ▼
第 3 步  类与注解改名(import、Jackson 3、测试注解)
   │   (依赖对了,改 import 时编译器只报"真正缺的")
   ▼
第 4 步  配置属性重命名与移除
   │   (编译通过了,才能安全地做启动期验证)
   ▼
第 5 步  自有自动配置 / starter 的注册文件沿革
   │
   ▼
第 6 步  测试写法适配

为什么第 0 步必须在最前:4.x 移除了 3.x 中所有已废弃的类、方法、属性。如果你带着废弃调用直接升到 4.x,会同时面对「废弃 API 被移除」和「模块化改名」两类错误,难以区分。先在 3.5.x 上把所有废弃警告清零,4.x 的报错就只剩模块化这一条线索。

11.2.2 第 0 步:在 3.5.x 上清废弃

对照线是 Spring Boot 3.5.16(Spring Framework 6.2.19,Servlet 6.0 / Jakarta EE 10,Jackson 2,Tomcat 10.1)。本机已实测跑通 3.5.16 与 4.1.1 两条版本线。

# 用编译器警告 + 静态检查找出所有废弃调用
# -Xlint:deprecation 会把每一处废弃 API 的位置打出来
javac -Xlint:deprecation -d /tmp/out $(find src/main/java -name '*.java')

在 Maven 里可以给 compiler 插件加 <compilerArgs><arg>-Xlint:deprecation</arg></compilerArgs>。目标是把警告数降到 0——每一条废弃警告,在 4.x 里都是一条必改项。

11.2.3 第 1 步:Java 与构建插件基线

4.x 的系统要求是硬门槛,先抬到位再动依赖:

项目3.5.x4.x
Java17(3.x 最低)17+,本系列用 21
Kotlin1.x 系2.2+
GraalVM native-image22/2325+
Jakarta EE1011
Servlet6.06.1
Spring Framework6.2.x7.x

Maven 侧的对应动作:

<properties>
  <java.version>21</java.version>
  <maven.compiler.release>21</maven.compiler.release>
</properties>

如果你手动管理 Spring Framework 版本,务必升到 7.x——4.x 与 Framework 6.x 不兼容。另外 4.1 起有一处构建插件行为变更:-DskipTests 不再跳过测试的 AOT 处理,Maven 插件只认 maven.test.skip。如果你的 CI 依赖 -DskipTests 来快速打包,升级后要么改用 maven.test.skip=true,要么接受 AOT 处理的开销。

11.2.4 第 2 步:依赖坐标与版本

2a. BOM 与 starter 改名。 把 spring-boot-starter-parent 或 spring-boot-dependencies 升到 4.1.1,然后按上一节的对照表改名 starter。最容易漏的是「以前不需要 starter、现在需要」的那类:

技术改动
Flyway加 spring-boot-starter-flyway
Liquibase加 spring-boot-starter-liquibase

2b. 依赖大版本对照。 4.0 与 4.1 的依赖版本不同,别混。下表左列是 4.0 引入的口径,右列是本机 spring-boot-dependencies-4.1.1.pom 实测口径:

依赖4.0 起4.1.1 实测
Spring Framework7.07.0.9
Spring Security7.07.1.1
Spring Data2025.12026.0.1
Spring Batch6.06.0.5
Spring Kafka4.04.1.1
Spring AMQP4.04.1.1
Hibernate ORM7.27.4.5.Final
Hibernate Validator9.09.1
HikariCP7.07.0.2
Tomcat11.011.0.24
Testcontainers2.02.0.5
Flyway11.1112.4.0
Jackson3.03.1.5
Micrometer1.161.17.1

写版本号时以「4.1.1 实测」列为准。 典型错误是写「4.x 用 Hibernate 7.2」——那是 4.0 的口径,4.1 已升到 7.4。凡是你项目里显式覆盖过版本的依赖(Spring Cloud、某些 driver),都要单独确认兼容版本。

2c. 被移除的依赖管理。 有两处需要特别注意:

  • Spring Retry:依赖管理被移除(Spring 生态转向 Framework 7 的核心重试能力)。如果你的代码仍依赖 Spring Retry,必须自己写版本号,并考虑迁到 Spring Framework。
  • Spring Authorization Server:并入 Spring Security 7.0。你不能再用 spring-authorization-server.version 覆盖版本,要改用 spring-security.version。

11.2.5 第 3 步:类与注解的移除与改名

依赖对了之后,编译器会精确报出「真正缺的类」。对照这张表逐项改:

3.x4.x说明
@MockBean已移除 → @MockitoBean测试用,见 11.2.7
@SpyBean已移除 → @MockitoSpyBean同上
Jackson2ObjectMapperBuilderCustomizerJsonMapperBuilderCustomizer包 org.springframework.boot.jackson.autoconfigure
@JsonComponent@JacksonComponent包 org.springframework.boot.jackson
@JsonMixin@JacksonMixin同上
@EntityScanorg.springframework.boot.persistence.autoconfigure.EntityScan包迁移
BootstrapRegistryorg.springframework.boot.bootstrap.BootstrapRegistry包迁移
EnvironmentPostProcessororg.springframework.boot.EnvironmentPostProcessor旧位置 org.springframework.boot.env 已废弃
org.springframework.lang.Nullableorg.jspecify.annotations.NullableJSpecify 空安全

这些名字都能从本机 jar 核实。测试注解的包名可以这样查(本机已下 7.0.9 的 spring-test):

# @MockitoBean 的真实包名
unzip -l /tmp/springboot_book/jars/spring-test-7.0.9.jar | rg 'MockitoBean\.class'

实测输出:org/springframework/test/context/bean/override/mockito/MockitoBean.class——即 org.springframework.test.context.bean.override.mockito.MockitoBean。注意 @MockitoBean 是 Spring Framework 的注解,不是 Spring Boot 的,所以它不在 spring-boot-* 的任何模块里。

Jackson 3 的类改名同样可核实:

unzip -l ~/.m2/repository/org/springframework/boot/spring-boot-jackson/4.1.1/spring-boot-jackson-4.1.1.jar \
  | rg 'JacksonComponent|JacksonMixin|JsonMapperBuilderCustomizer'

11.2.6 第 4 步:配置属性重命名与移除

属性改名的原则是「先让工具帮你找,再逐条改」。官方提供了一个迁移器模块:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-properties-migrator</artifactId>
  <scope>runtime</scope>
</dependency>

它会分析应用的 Environment,在启动时打印诊断,并在运行时临时帮你迁移属性。迁移完成后必须删掉它,否则每次启动都在做无谓的属性映射。

下面这张表是从官方 4.0 配置变更日志里核实过的常见重命名,按影响面排序:

3.x4.x
spring.http.client.*spring.http.clients.*
spring.http.reactiveclient.*spring.http.clients.* / spring.http.clients.reactive.*
spring.data.mongodb.host/port/uri/...(driver 相关)spring.mongodb.*
spring.session.redis.*spring.session.data.redis.*
spring.dao.exceptiontranslation.enabledspring.persistence.exceptiontranslation.enabled
management.health.mongo.enabledmanagement.health.mongodb.enabled
management.health.probes.enabledmanagement.endpoint.health.probes.enabled
management.endpoint.<id>.enabledmanagement.endpoint.<id>.access
management.metrics.mongo.*management.metrics.mongodb.*

有几条要单独拎出来:

  • management.endpoint.<id>.enabled → .access 是一整族变更,Actuator 的每个端点都受影响。别只改一个就以为改完了。
  • MongoDB 的属性拆分很微妙:只有「仅需 driver」的属性才从 spring.data.mongodb 改成 spring.mongodb;需要 Spring Data MongoDB 的(如 spring.data.mongodb.auto-index-creation、spring.data.mongodb.repositories.type)保持不变。改错方向会让配置静默不生效。
  • Jackson 属性:spring.jackson.read.* / write.*(JSON 专属)在 4.0 挪到 spring.jackson.json.read / .write;spring.jackson.parser.* 被 spring.jackson.json.read 取代。4.1 又把跨格式通用的 spring.jackson.read.* / write.* 重新引入(作用于 CBOR/JSON/XML 共有特性)。所以同名属性在 4.0 和 4.1 含义不同,升级时务必分清。

11.2.7 第 5 步:spring.factories 到 AutoConfiguration.imports 的沿革

如果你自己写过 starter 或自动配置,这一条必须懂。注册自动配置的机制经历了两代:

版本机制状态
2.xMETA-INF/spring.factories,键 org.springframework.boot.autoconfigure.EnableAutoConfiguration旧机制
2.7引入 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports,同时兼容 spring.factories过渡期
3.0移除 spring.factories 里 EnableAutoConfiguration 键的支持只认 imports 文件
4.x模块化后,每个模块各自持有自己的 AutoConfiguration.imports现行

也就是说,从 3.0 起 spring.factories 里写自动配置就已经不生效了;4.x 进一步把「谁登记自动配置」按模块拆开——每个技术模块只登记自己的。spring.factories 里其它键(如 org.springframework.boot.env.EnvironmentPostProcessor)仍有效,不受影响。

你可以直接看本机模块的登记文件,验证「各模块各管各的」:

# 数一数各模块登记了几条自动配置
for m in spring-boot-autoconfigure spring-boot-webmvc spring-boot-tomcat spring-boot-jackson; do
  n=$(unzip -p ~/.m2/repository/org/springframework/boot/$m/4.1.1/$m-4.1.1.jar \
        META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 2>/dev/null | rg -c .)
  echo "$m: $n"
done

本机实测:spring-boot-autoconfigure: 12、spring-boot-webmvc: 6、spring-boot-tomcat: 5、spring-boot-jackson: 1。

还有一处历史遗留要注意:spring.factories 里注册 EnvironmentPostProcessor 的键在 4.0 仍然有效,但该接口的包名变了(见 11.2.5)。如果你的 spring.factories 里写了旧包名,它会静默失效——这类「注册了但不生效」的问题比编译错误难查得多。

11.2.8 第 6 步:测试写法适配

4.0 的测试层变化集中且容易漏,单列一张表:

3.x4.x
@MockBean / @SpyBean已移除 → @MockitoBean / @MockitoSpyBean
@SpringBootTest 自带 MockMvc需加 @AutoConfigureMockMvc
@SpringBootTest 自带 TestRestTemplate需加 @AutoConfigureTestRestTemplate
MockitoTestExecutionListener已移除,改用 Mockito 的 MockitoExtension
@PropertyMapping移到 org.springframework.boot.test.context
—新增 RestTestClient + @AutoConfigureRestTestClient

@MockitoBean 有一个关键差异:它可以用作测试类的字段,但不能用在 @Configuration 类里。3.x 里常见的「用一个 @TestConfiguration 集中声明一批 mock」的写法在 4.x 会失败。替代做法是把它们直接标在测试类上:

@SpringBootTest
@MockitoBean(types = {OrderService.class, UserService.class})
@MockitoBean(name = "ps1", types = PrintingService.class)
class ApplicationTests {

    @Test
    void check() {
        // ...
    }
}

如果这类共享 mock 很多、写在测试类上不现实,可以自定义一个组合注解:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@MockitoBean(types = {OrderService.class, UserService.class})
@MockitoBean(name = "ps1", types = PrintingService.class)
public @interface SharedMocks {
}

测试模块的引入也要注意:@WithMockUser / @WithUserDetails 现在需要 spring-boot-starter-security-test 才能正常工作,只引 spring-boot-starter-test 不够。而所有 spring-boot-starter-<tech>-test 都会传递 spring-boot-starter-test,所以正确做法是「引被测技术对应的 test starter」,而不是继续显式引 spring-boot-starter-test。

11.2.9 属性元数据:最权威的核实手段

改配置属性时,不要靠记忆,也不要靠搜索引擎。每个模块 jar 里都有 META-INF/spring-configuration-metadata.json,它才是属性名最权威的来源:

# 列出 spring.jackson 命名空间下所有真实存在的属性
unzip -p ~/.m2/repository/org/springframework/boot/spring-boot-jackson/4.1.1/spring-boot-jackson-4.1.1.jar \
  META-INF/spring-configuration-metadata.json | rg -o '"name": "spring\.jackson\.[^"]*"' | sort -u

本机实测能确认 spring.jackson.json.read、spring.jackson.json.write、spring.jackson.read、spring.jackson.write、spring.jackson.parser、spring.jackson.find-and-add-modules、spring.jackson.use-jackson2-defaults 都存在——这直接印证了 11.2.6 里「4.0 挪到 json 子命名空间、4.1 又重引入通用读写」的判断。当文档、记忆、博客三者的说法冲突时,以这个 json 为准。

小结

这一节的核心不是那张长长的改名表,而是步骤之间的依赖关系:清废弃 → 抬基线 → 定依赖 → 改代码 → 改配置 → 改注册 → 改测试,每一步都为下一步扫清干扰。

  • 第 0 步在 3.5.x 上把废弃调用清零,4.x 的报错才会只剩模块化一条线索。
  • 基线先抬:Java 17+/21、Jakarta EE 11、Servlet 6.1、Spring Framework 7.x;4.1 起 -DskipTests 不再跳过 AOT,改用 maven.test.skip。
  • 依赖改名 + 补 Flyway / Liquibase starter;版本以 4.1.1 实测口径为准,别混 4.0 与 4.1。
  • 类与注解改名集中在 Jackson 3、JSpecify、包迁移三块;@MockitoBean 属于 Spring Framework 而非 Boot。
  • 配置属性用 spring-boot-properties-migrator 辅助,改完必须移除;MongoDB 属性按「是否仅需 driver」拆分。
  • spring.factories 注册自动配置从 3.0 起已失效,4.x 改为每模块各持 AutoConfiguration.imports。
  • 属性名有疑问就 unzip 读 spring-configuration-metadata.json。

清单能保证「不漏项」,但保证不了「不出错」。下一节讲迁移过程中怎么分批验证、哪些改动不可回滚、什么情况下应当干脆放弃迁移。

阅读导航:上一节:11.1 Spring Boot 4 的模块化重构 · 下一节:11.3 迁移实测与回滚策略 。

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「java」更多文章

  1. 《Spring Boot 入门》18.3 打包与运行
  2. 《Spring Boot 入门》18.2 实现
  3. 《Spring Boot 入门》18.1 需求与设计