Spring Boot 4 迁移指南:模块化重构带来什么、破坏什么

一、要不要迁:时间线先把这个问题定死

Spring Boot 3 的入门认知站内已有《Spring Boot 框架入门》打底,这一篇假设你已经写过 3.x 项目,只回答一个问题:3.x 到 4.x 这一跳,带来什么、破坏什么、怎么迁。先把时间线摊开,因为”要不要迁”不是靠感觉,是靠支持周期到期日定死的:

时间 事件 对”要不要迁”的含义
2025-05 Spring Boot 3.5 发布(3.x 最后一条线) 3.x 进入收尾,新特性不再来
2025-11-13 Spring Framework 7.0 GA 新一代基座就位
2025-11-20 Spring Boot 4.0 发布(Maven Central) 迁移目标出现
2026 年内 3.x 各线开源支持陆续到期;4.0 的开源支持到 2026-12-31(官方支持页口径) 2027 年还停在 3.x = 拿不到开源补丁,迁移从可选项变成到期事务
撰写时(2027-04) 4.x 的后续维护线(4.1.x 起)为当前活跃线 迁就迁到当时的最新补丁线,不要停在 4.0.0

再看运行基线,好消息是这次没有强制搬家:

基线项 Spring Boot 3.x Spring Boot 4.x 你要动吗
Java 17 起 17 起(没升基线),Java 25 为一等支持(最新 LTS) 不强制;生产建议顺势上 25
Jakarta EE EE 10 / Servlet 6.0 EE 11 / Servlet 6.1 内嵌容器随版本走(Tomcat 11),一般无感
Jackson 2.x 默认 3.x 默认(包名 tools.jackson) 要动,见第四节

Java 基线留在 17 是这代升级最大的善意:上一跳(2.x 到 3.x)最疼的 javax 到 jakarta 迁移这代没有对应物,多数项目的工作量集中在”模块化拆分的连锁反应 + 弃用清理”两件事上——正好是下两节的主角。

二、模块化重构:带来什么

Boot 4 最大的结构性变化是把那块”什么都有”的 spring-boot-autoconfigure 巨型 jar 拆成了按技术粒度的一组模块——Web 服务器、数据访问、缓存、消息,各有各的自动配置模块(如 spring-boot-web-server-autoconfigure 这类命名)。官方博客的说法是”模块化 Spring Boot”,注意这里的”模块”指的是 jar 拆分,不是 JPMS(Java 平台模块系统),别被词吓到。

对普通应用开发者,这个拆分大部分被 starter 屏蔽了:starter 会替你声明它需要的自动配置模块,多数应用改个版本号就能编译。它真正改变的是两件事。第一,装配更可解释。以前排查”这个 Bean 从哪来的”要在一个巨型 jar 里翻;现在按技术分家,条件评估报告与源码组织对得上,排障时少一层迷雾。第二,依赖图更诚实。以前一个传递依赖就能把整块自动配置拖进来;拆分后,用了什么就声明什么,类路径上少一堆”不知道为什么在”的候选配置。

三、破坏什么:三类高频断裂点

断裂点一:spring.autoconfigure.exclude 里的类搬家了

3.x 里按完整类名排除自动配置的配置项,在 4.0 里会因为类迁入新技术模块而失效——失效方式是启动期找不到类,属于”一启动就炸”的友好型破坏。修法是把每个条目按官方迁移指南的对照表重定位;OpenRewrite / Moderne 提供了自动重定位这类条目的迁移配方,条目多的项目值得先跑一遍再人肉核对:

# application.yml / application.properties
1. 3.x 写法:按旧 FQN 排除
1. spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration
1. 4.0:类已迁入按技术命名的新模块,完整类名以官方迁移指南对照表为准,逐条重定位

断裂点二:自定义 starter 与三方 starter

这是拆分冲击最大的人群。3.x 时代写自定义 starter 有个普遍的隐性假设:classpath 上有 spring-boot-autoconfigure 这块”大杂烩”,自己的自动配置类随便引用其中任何类都编译得过。4.0 里这个假设作废——每个 starter 需要显式声明并依赖自己所属技术的那块自动配置模块。给团队内部框架的维护者列一张对照:

关注点 3.x 的习惯 4.0 要做什么
依赖声明 依赖 spring-boot-autoconfigure 一把梭 按用到的技术显式依赖对应的自动配置模块(Web、JDBC、Flyway 各归各)
自动配置注册 META-INF/spring 下的 imports 声明 注册机制延续,但类的所在 artifact 变了,打包关系要重排(以官方迁移指南为准)
使用方的排除项 旧 FQN 发布迁移说明,告知使用方同步重定位 exclude 条目
验证方式 “编译过就行” 必须在一个真实 4.x 应用里做装配冒烟:自动配置缺失在编译期不报错,只在运行期静默缺失

反模式一:靠传递依赖”顺带”拿到自动配置。4.0 下这是最典型的静默故障源——starter 编译通过、发布成功、使用方启动也成功,只是某个该自动装配的 Bean 没了,最后以 NoSuchBeanDefinition 的形式在离根因很远的地方爆出来。自定义 starter 在 4.x 下的纪律是:用哪块、声明哪块、测哪块。

断裂点三:3.x 生命周期内的弃用一次性全删

官方迁移指南的口径很硬:3.x 期间标记弃用的类、方法、属性,在 4.0 里全部移除,没有缓冲期。这意味着”在 3.5 上能编译过”不等于”在 4.0 上能编译过”——那些年你忽略掉的弃用告警,这一版集中结账。几个社区实测里高频命中的具体项:

弃用/移除项 3.x 行为 4.0 行为 迁移动作
全部 3.x 弃用 API 标记弃用仍可用 移除 先在 3.5 上开 -Wdeprecation 或跑 OpenRewrite 清零告警,再升版本
H2 控制台 classpath 有 H2 即随 Actuator 暴露 不再默认包含 开发环境需要的话按迁移指南显式补模块与配置
Spring Security 旧 DSL 可用(带弃用告警) 移除,要求显式配置 按新版安全配置清单逐段重写;迁移后必须做行为回归,见第七节
Jackson 2 默认装配 默认 2.x 默认 3.x,包名 com.fasterxml.jackson 改为 tools.jackson 两步走,见下节

四、Jackson 3:唯一建议”分两步”的项

Jackson 3 换了坐标(tools.jackson 命名空间)也改了一批默认行为,是这次升级里改动面最广的单项。好消息是官方明确支持 Jackson 2 与 3 共存,所以迁移策略可以解耦:先升 Boot 4、暂留 Jackson 2(显式声明 ObjectMapper 与消息转换器 Bean),让应用先跑起来;再单独开一个分支做 import 全局替换与默认行为对齐。一步到位当然也行,但把”框架升级”和”序列化行为变更”两件高风险事叠在同一次发布里,出问题时你分不清是哪边引入的。

五、内建 retry:少一个依赖,多一套语义

这代升级里少见的”净赚”项:Spring Retry 作为独立项目并进了 Framework 7 的 spring-core,@Retryable、RetryTemplate 成为框架原生能力,不用再单独引入 spring-retry 依赖,还附赠了并发闸门 @ConcurrencyLimit;注解用在返回 Mono/Flux 的方法上时,会自动改用 Reactor 的 retry 算子而不是阻塞式重试。示例:

@Service
public class InvoiceClient {

    // 注意语义:maxRetries 是"重试次数",3 表示首次调用之外再试 3 次
    // 旧 spring-retry 的 maxAttempts 是"总尝试次数",迁移时数字不能照抄,见下表
    @Retryable(maxRetries = 3)
    public Invoice fetch(String id) {
        // 调外部发票服务,失败由框架按注解重试
        return gateway.get(id);
    }

    // 并发闸门:同时只放行 10 个调用,超出的快速失败
    // 保护的是下游,也保护自己线程池——与 retry 同属这代的弹性能力包
    @ConcurrencyLimit(10)
    public void push(String id) {
        gateway.notify(id);
    }
}
维度 旧 spring-retry Framework 7 内建
依赖 org.springframework.retry:spring-retry 单独引入 spring-core 自带,去掉依赖
注解计数语义 maxAttempts:总尝试次数(含首次) maxRetries:重试次数(不含首次)
程序式 API RetryTemplate RetryTemplate(随能力一并并入 core)
响应式 不覆盖 Mono/Flux 返回值自动走 Reactor retry
附加能力 — @ConcurrencyLimit 并发闸门

反模式二:把 maxAttempts 的值原样搬给 maxRetries。旧值 4 表示”首次 + 3 次重试”,照抄成 maxRetries = 4 就变成 4 次重试,重试压力多一轮、超时窗口变长——这种错不报编译错误,只在下游故障时的报警曲线里现形。迁移时把项目里所有手写重试计数列出来逐个换算(maxAttempts 等于 maxRetries 加一)。

六、迁移步骤清单

顺序本身是正确性的一部分,别按喜好重排:

步骤 做什么 为什么在这个位置
前置清障 升到 3.5 最新补丁;开 -Wdeprecation 清零弃用告警(或跑 OpenRewrite 的 Boot 4 配方) 3.x 弃用在 4.0 全删;在 3.5 上清,问题定位还有旧版本上下文
依赖矩阵对齐 确认 Spring Cloud、三方 starter、内部 starter 都有 4.x 兼容版本,先升它们 任何一块没跟上,主工程升了也起不来
主工程升版本 Spring Boot 升到当时的最新 4.x 补丁线;处理编译错误(exclude 条目重定位、自动配置类搬迁、Jackson import) 放在清障后,编译错误的”新账”才不会和弃用的”旧账”混在一起
Jackson 决策 暂留 2(显式 Bean)或整体切 3 见第四节,两步走时这步只做”声明保持”
安全配置重写 旧 DSL 移除后的 Security 配置按新写法重写 放编译通过之后、回归之前,重写完必须全量回归
回归清单 按下一节的清单逐项过 升级造成的故障多数不在编译期现形

七、回归清单

回归项 怎么验 防的是哪类断裂
自动配置完整性 启动加 --debug 看条件评估报告;对照 3.x 时代的报告 diff 一遍 拆分导致的静默缺失(本文第三节)
Actuator 端点 全量端点逐个 curl,对齐暴露列表 模块拆分后端点装配变化
安全行为 匿名/认证/越权三类请求路径各打一遍(自动化测试最好) Security 旧 DSL 移除后的默认行为变化
JSON 序列化 关键接口的请求/响应做快照对比(空值、日期格式、未知字段策略) Jackson 3 默认行为差异
重试与超时 故障注入:下游超时/报错时观测实际重试次数与间隔 maxAttempts 到 maxRetries 的语义差
内部 starter 使用方 每个依赖方应用至少一次完整启动 + 核心链路冒烟 自定义 starter 的装配静默缺失

八、诚实结论

这一跳的真实工作量分布:没有自定义/三方 starter 依赖、没有重度安全定制的小服务,多数是半天级——升版本、清弃用、跑回归;有内部 starter 的团队,工作量在 starter 侧而不是应用侧,且必须为”使用方静默装配缺失”准备专门的冒烟流程,预算按天算。判断顺序建议:先盘依赖矩阵(Spring Cloud、三方、内部 starter 有没有 4.x 线),再定排期——矩阵里任何一块没有 4.x 兼容版本,你单独迁主工程就是在制造一个起不来的分支。Java 语言侧配套的语法基线变化,可参见《Java 现代语法特性》。

版本核实(以官方文档为准):Spring Framework 7.0 GA 于 2025-11-13、Spring Boot 4.0 于 2025-11-20 发布(spring.io 官方公告);Java 基线 17 未升、Java 25 一等支持(官方公告口径);4.0 开源支持至 2026-12-31(官方支持页),撰写时 4.1.x 为活跃维护线;模块化拆分(spring-boot-autoconfigure 按技术拆分、非 JPMS)、exclude 条目重定位(Moderne/OpenRewrite 迁移配方)、Jackson 3(tools.jackson,官方博客明确 2/3 可共存)、spring-retry 并入 spring-core 与 maxRetries 语义、@ConcurrencyLimit(官方博客 Core Spring Resilience Features)、H2 控制台默认不暴露与 Security 旧 DSL 移除(社区实测记录,以官方迁移指南为准)。一切以 docs.spring.io 与 GitHub 官方迁移指南为准。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇