2026年6月,Spring Boot 3.5.x的开源支持正式结束。这意味着3.5及更早的3.x版本不再收到社区安全补丁和Bug修复。如果你还在用Spring Boot 3.3、3.4或3.5,迁移到4.0已经不是"要不要做"的问题,而是"什么时候做"的问题。
Spring Boot 4.0在2025年11月发布,基于Spring Framework 7,截至8月最新补丁版本是4.0.7,4.1.0-RC1也已经发布。生态已经成熟,但迁移不是换个版本号那么简单。以下五个变化,是迁移过程中最容易踩坑的地方。

坑一:虚拟线程默认化,线程池配置要重写
Spring Boot 4.0最大的变化之一:虚拟线程从3.2的"opt-in实验特性"变成了"推荐默认值"。在Java 21+环境中,Tomcat和Jetty的请求处理线程默认使用虚拟线程,@Async任务和定时任务也遵循同一模型。
这意味着原来精心配置的线程池参数可能不再适用。如果你在3.x中为高并发场景引入了Reactor或WebFlux响应式框架,现在需要重新评估:虚拟线程用同步代码就能达到类似的吞吐量,响应式框架的引入理由是否还成立?
迁移时需要检查的配置项:
spring.threads.virtual.enabled(4.0中默认为true)- 自定义的
ThreadPoolTaskExecutor配置是否与虚拟线程冲突 ThreadLocal的使用模式——虚拟线程可以创建数百万实例,ThreadLocal的清理策略需要重新审视- CPU密集型任务不受益于虚拟线程,需要单独配置平台线程池
坑二:模块化Starter重设计,依赖路径变了
Spring Boot 4.0对整个代码库进行了模块化重构。原来一个2MB的spring-boot-autoconfigure大包包含了几乎所有技术的自动配置,现在拆成了多个聚焦的小模块:spring-boot-jdbc、spring-boot-webmvc、spring-boot-data-jpa等。
对大多数使用Starter POM的项目,pom.xml或build.gradle不需要改——模块化发生在Starter底层。但如果你有自定义的auto-configuration,或者直接引用了Spring Boot内部auto-configuration类的public成员,就会遇到编译错误——这些成员在4.0中变成了package-private。
迁移时要重点检查的代码:
- 直接继承
AutoConfiguration类的自定义配置 - 引用
spring-boot-autoconfigure内部类的import路径 - 第三方Starter是否已发布4.x兼容版本(社区Starter通常滞后于主版本)
坑三:Jackson 2到Jackson 3的升级
Spring Boot 4.0将Jackson 3作为默认JSON库,Jackson 2.x以deprecated形式保留。这不是简单的版本号升级——Jackson 3的包名从com.fasterxml.jackson迁移到了tools.jackson,API也有变化。
如果你的项目中有自定义的Jackson配置——比如自定义ObjectMapper Bean、自定义序列化器/反序列化器、@JsonFormat注解的使用——迁移时需要逐项检查。Jackson 2和Jackson 3可以共存于同一个项目(用于渐进式迁移),但长期共存会增加维护复杂度。
坑四:JSpecify空安全注解,编译期检查更严格
Spring Boot 4.0在全家桶层面引入了JSpecify空安全注解。默认情况下,所有Spring API的返回值和参数都标记为非null,可空的用@Nullable显式标注。
IntelliJ IDEA 2025.3+和Eclipse已经支持这些注解,会在编译期发出警告。如果你的代码中有"可能返回null但调用方没有检查"的模式,迁移后会看到大量警告。好消息是这些只是警告不是错误,但逐个处理的工作量不小——可以按包逐步添加@NullMarked注解,渐进式解决。
Kotlin项目还有一个额外收益:Kotlin 2会自动将JSpecify注解转换为Kotlin的空安全系统,困扰已久的platform types问题在Spring Boot 4 + Kotlin项目中基本消失。
坑五:Spring Framework 7的API版本控制
Spring Framework 7引入了原生的API版本控制支持。原来每个项目自创的/v1/路径前缀、自定义Header、媒体类型版本参数,现在有了官方方案:
@Configuration
public class WebConfiguration implements WebMvcConfigurer {
@Override
public void configureApiVersioning(ApiVersionConfigurer configurer) {
configurer.useRequestHeader("API-Version");
}
}
@RestController
public class AccountController {
@GetMapping(path = "/account/{id}", version = "1.1")
public Account getAccount() { ... }
@GetMapping(path = "/account/{id}", version = "1.2+")
public AccountV2 getAccountV2() { ... }
}
1.2+表示从1.2版本开始生效,直到被新版本替代。内置的废弃处理器会按照RFC 9745和RFC 8594自动设置HTTP Header,给API客户端结构化的迁移通知。
这不是breaking change,但如果你在3.x中自建了API版本控制方案,迁移时需要评估是否替换为官方方案——两套版本控制共存会让API路由变得混乱。
迁移不只是改版本号
Spring Boot 4.0的迁移路径是:3.x → 3.5 → 4.0。官方提供了3.x到4.0的迁移指南,也有OpenRewrite配方可以自动化部分重构工作。但五个坑的共同特征是:它们都不是"编译报错改一改"能解决的,而是需要重新审视项目的运行时配置、依赖结构和API设计。
对于还在用Spring Boot 2.x的团队,迁移路径更长:2.x(javax.* 命名空间)→ 3.x(jakarta.* 命名空间)→ 4.0。两步跳之间涉及的命名空间迁移、Java版本升级(2.x支持Java 8,4.0最低Java 17)和依赖链更新,工作量不小。
在框架升级场景下,AI工具的价值不在于"帮你写新代码",而在于"帮你评估迁移影响"。以飞算JavaAI的框架升级器为例,它覆盖Spring Boot 2.0到4.0、Spring Framework 3.0到7.0等40+框架的上百个版本,扫描项目中的版本兼容性问题——API废弃、依赖冲突、配置变更——并生成迁移建议。这种工作不是生成代码,而是做工程决策分析,需要的是对整个项目的影响评估而非单文件修改。

结语
Spring Boot 3.5的开源支持已经结束。4.0不是可选升级,而是必须完成的迁移。五个坑——虚拟线程配置、模块化Starter、Jackson 3、JSpecify空安全、API版本控制——每一个都需要认真对待。
迁移窗口正在缩小。Spring Boot 4.0的开源支持到2026年12月,4.1已经发布RC版本。越晚迁移,积累的技术债越重。如果你的团队还在3.x上,现在是制定迁移计划的时候了。
169

被折叠的 条评论
为什么被折叠?



