首页 / Spring Boot 入门教程 / 从 2.x 和 3.x 迁移到 4.x

Spring Boot 入门教程

从 2.x 和 3.x 迁移到 4.x

本教程共 48 篇 · 第 46 篇 · 更新于 2026-08-13 · 约 6 分钟阅读

版本迁移升级JakartaSpring Framework 74.x 新特性spring-boot-properties-migratorJackson 3Starter

本节目标:看懂 Spring Boot 2.x、3.x、4.x 之间的差异,学会按官方流程把老项目平滑升级到 4.1.0,并了解 4.x 带来了哪些新东西。

先看版本线

Spring Boot 的版本有自己的生命周期。升级不是选择题,而是迟早要做的事。

  • 2.7.x 及更早:已停止维护,建议尽快离开。
  • 3.5.16(2026-06-25):3.x 维护线的最后一个 OSS 补丁,社区支持已结束,仅剩商业支持。
  • 4.0.7:4.0 维护线,负责修 4.0 的小问题。
  • 4.1.0:2026-06-10 发布的 GA 版本,本教程的基线。

大版本升级会带来破坏性变化。2.x 到 3.x 是一次「伤筋动骨」,3.x 到 4.x 又是一次。本教程主线代码全部基于 4.1.0,这章专门讲「老代码怎么搬」。

2.x → 3.x:javax 到 jakarta 的大迁徙

2.x 升 3.x 最痛的改动,是把整个 Java EE 命名空间从 javax.* 换成了 jakarta.*

原因是 Oracle 把 Java EE 捐给了 Eclipse 基金会,新名字叫 Jakarta EE。包名必须跟着改,否则依赖会冲突。

// 2.x 时代:javax 包
import javax.persistence.Entity;
import javax.servlet.http.HttpServletRequest;

// 3.x 起:jakarta 包
import jakarta.persistence.Entity;
import jakarta.servlet.http.HttpServletRequest;

改的不只是 import。3.x 还同时做了这些调整:

  • Java 基线升到 17,Spring Framework 6。
  • Spring Security 6:安全配置改为 Lambda DSL 写法。
  • 配置键改名:spring.redis.* 移到 spring.data.redis.*server.max.http.header.size 改为 server.max-http-request-header-size
  • URL 尾斜杠默认不再匹配:GET /user/ 不再等于 GET /user
  • Actuator 的 /httptrace 端点改名 /httpexchanges
  • HTTP 客户端升级到 Apache HttpClient 5。
  • MySQL 驱动坐标改为 com.mysql:mysql-connector-j
  • Hibernate 升到 6.x,JPA 规范升到 3.1。

这批改动里,配置键变化最容易踩坑。官方给了一个侦探工具,下一节讲。

3.x → 4.x:模块化与新基线

4.0(2025-11-20 发布)基于 Spring Framework 7,底层标准全面升级:

  • Jakarta EE 11:Servlet 6.1、JPA 3.2、Bean Validation 3.1。
  • 最低 Java 17,官方一等公民支持 Java 25,生产可选 21/25 LTS,Boot 4.x 支持至 26。
  • Jackson 3:JSON 库换代,包名从 com.fasterxml.jackson 改为 tools.jackson
  • RestTemplate 正式弃用,主线用 RestClient / WebClient。

好消息是:3.x 已经是 jakarta.* 了,4.x 不需要再来一次大规模改名。

Starter 改名了

4.x 把框架做了模块化,一批 starter 改了名,语义更精确。最常见的:

3.x 旧名4.x 新名
spring-boot-starter-webspring-boot-starter-webmvc
其余技术专属 starter同名保留或按新模块拆分

旧名字的 POM 会作为「classic」桥接依赖继续存在,但已标记弃用。升级时建议直接换新名,别用桥接凑合。

<!-- 3.x 写法 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- 4.x 写法 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webmvc</artifactId>
</dependency>

4.x 移除或改名的东西

  • 移除 Undertow 嵌入式服务器支持。
  • 测试注解 @MockBean@SpyBean 被移除,改用 @MockitoBean@MockitoSpyBean
  • @SpringBootTest 不再自动装配 MockMvc,需要显式加 @AutoConfigureMockMvc
  • 移除嵌入式 init.d 风格启动脚本。
  • 配置属性又有一轮改名/删除,靠迁移工具定位。

官方推荐的迁移步骤

迁移的节奏比内容更重要。官方建议:一次跨一个大版本,别一口气跳两级。

  1. 升级前检查。确认 Java 版本满足要求(4.x 需要 17+),构建工具(Maven/Gradle)够新,第三方依赖有 4.x 兼容版本。
  2. 先升到当前大版本的最后一个小版本。比如 2.7.x 先升 3.5.16,清理掉所有弃用警告,再升 4.1.0。3.x 里标弃用的 API,4.0 里可能直接删了。
  3. 加 properties-migrator 找配置问题。这是官方提供的运行时诊断工具。
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-properties-migrator</artifactId>
    <scope>runtime</scope>
</dependency>

启动应用后,它会在日志里列出所有改名或删除的配置键,并在运行时临时帮你迁移。

Warning

迁移完成后必须删掉这个依赖。它只是过渡工具,留在生产代码里是隐患。

  1. 批量处理代码差异javax.*jakarta.*(2.x 用户)、Jackson 3 包名、测试注解更名、RestTemplateRestClient
  2. 更新构建文件。换新 starter 名,核对依赖坐标。
  3. 跑回归测试。接口行为、配置加载、启动日志逐项验证。

大型项目可以借助 OpenRewrite 这类自动化重构工具。它有一整套 Spring Boot 升级 recipe,能自动改包名和配置键,减少手工遗漏。

Note

升级前先看一遍官方对应版本的迁移指南和 Release Notes(升级说明永远是发布说明里的第一项)。跨多个版本升级时,中间跳过的每个版本说明都要过一遍,很多坑就藏在里面。

常见坑位对照

迁移路上有几个高频坑,提前对照可以少走弯路。

Jackson 3 包名。4.x 默认 JSON 库换成 Jackson 3,包名从 com.fasterxml.jackson 变成 tools.jackson。代码里直接 new 的 ObjectMapper、自定义的序列化器都要改 import。

// 3.x:com.fasterxml.jackson 包
import com.fasterxml.jackson.databind.ObjectMapper;

// 4.x:tools.jackson 包
import tools.jackson.databind.ObjectMapper;

测试注解更名@MockBean@SpyBean 在 4.x 被移除,换成新注解:

// 3.x 写法(已移除)
@MockBean
private UserRepository userRepository;

// 4.x 写法
@MockitoBean
private UserRepository userRepository;

Spring Security 7。Boot 4 配套 Security 7,Security 6 的写法基本兼容,但 lambda DSL 是唯一推荐写法,老的链式 .and() 风格会直接编译不过。

第三方依赖。Lombok、MyBatis、各云厂商 SDK 这些不在 Boot 管理范围内的库,升级前先查它们有没有支持 4.x 的版本,否则会遇到莫名其妙的类冲突。

4.x 新特性总览

迁移不是纯受罪,4.x 也带来实打实的新能力。

  • API 版本化:Spring MVC 支持 version 属性,同一个路径按版本分发。配置在 spring.mvc.apiversion.*,或用 ApiVersionConfigurer 定制。
  • 官方 OpenTelemetry starterspring-boot-starter-opentelemetry,指标、链路、日志统一走 OTLP 协议导出,原生镜像也支持。
  • HTTP Interface Client:Spring 6 引入、4.x 增强,用接口声明式调用远程 REST 服务,不再手写模板代码。
  • JSpecify 编译期空安全:注解驱动,IDE 里就能抓到空指针隐患。
  • GraalVM 原生镜像一等公民:AOT 编译路径更顺,启动更快。
  • REST Test Client:测试 REST 接口的新客户端,和 HTTP Interface Client 配套使用。

来一个最小的 API 版本化示例,感受 4.x 的新写法:

@RestController
public class VersionController {

    @GetMapping("/user", version = "1.0")
    public String userV1() {
        return "老版本接口";
    }

    @GetMapping("/user", version = "2.0")
    public String userV2() {
        return "新版本接口";
    }
}

再配合配置选择版本策略:

# 支持哪些版本
spring.mvc.apiversion.supported=1.0,2.0
spring.mvc.apiversion.default=1.0
# 用路径段策略:/1.0/user、/2.0/user
spring.mvc.apiversion.use.path-segment=1

访问路径为 /1.0/user/2.0/user。path-segment 策略下,版本段由解析器消费,不会作为普通路径变量出现。

小结

迁移的关键词是「按部就班」:先升到老版本线的最新,清干净弃用警告,用 migrator 找配置键,再处理代码差异,最后回归测试。2.x 用户多一道 javaxjakarta 的工序;3.x 用户重点看 starter 改名、Jackson 3 和测试注解。升级完成后,记得尝尝 4.x 的 API 版本化和 OpenTelemetry 两道新菜。