Featured image of post Spring Boot 3 与 Spring 6 的变化与迁移

Spring Boot 3 与 Spring 6 的变化与迁移

Java 17 基线、Jakarta 命名空间、原生镜像、Observability——Spring Boot 3 不是小升级,本文讲清要点和迁移建议

写在前面

Spring Boot 3.0 / Spring 6.0 在 2022 年 11 月发布,是 Spring 自 Spring 4.0 以来最大的一次跃迁。它不只是版本号 +1——而是整个技术栈的重新对齐:

  • Java 17 是最低基线——告别 Java 8/11
  • 从 javax 到 jakarta——命名空间彻底切换
  • GraalVM 原生镜像支持——启动时间从秒级到毫秒级
  • 内置 Observability——Micrometer + OTel
  • Servlet 6.0 / Jakarta EE 10

本文讲清楚这些变化、为什么这么变、升级要踩什么坑、什么场景该升、什么场景缓一缓。


一、最大的变化:javax → jakarta

这是最容易踩的坑——所有从 javax. 开始的标准库包名都改成了 jakarta.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
// Spring Boot 2.x
import javax.servlet.http.HttpServletRequest;
import javax.persistence.Entity;
import javax.validation.constraints.NotNull;
import javax.annotation.Resource;

// Spring Boot 3.x
import jakarta.servlet.http.HttpServletRequest;
import jakarta.persistence.Entity;
import jakarta.validation.constraints.NotNull;
import jakarta.annotation.Resource;

为什么改

Java EE 在 2017 年捐给 Eclipse 基金会成为 Jakarta EE。2019 年 Oracle 正式禁止 Eclipse 在新版本中继续使用 javax.*——所以从 Jakarta EE 9 开始全部改成 jakarta.*。Spring 6 跟着改。

升级痛点

  • 依赖的第三方库要全是 Jakarta 兼容版本——MyBatis、Hibernate、Druid、各种 starter 都要升级
  • 大量 import 要批量替换——IDE 有自动迁移工具,但要 review
  • 老的 javax 库没升级 → 直接编译失败

如果项目里有依赖仍在用 javax——升 Spring Boot 3 之前必须先确认所有依赖都有兼容版本。


二、Java 17 最低基线

Spring Boot 3 强制 Java 17+——告别 Java 8/11。

Java 17 给你的礼物

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// Records(数据载体)
public record UserDTO(Long id, String name, Integer age) {}

// Sealed classes
public sealed interface Shape permits Circle, Square {}

// Pattern matching for instanceof
if (obj instanceof String s && s.length() > 5) { ... }

// Switch expressions
String result = switch (status) {
    case "A" -> "Active";
    case "I" -> "Inactive";
    default -> "Unknown";
};

// Text blocks(多行字符串)
String json = """
    {
        "name": "test",
        "age": 30
    }
    """;

这些特性早几年就有,但Spring Boot 3 让你必须用 Java 17——团队终于有理由全员升级。

升级痛点

  • Java 8/11 的 build 脚本要改
  • 某些第三方库(特别是字节码操作类)要升级——CGLIB、ASM、Lombok 等
  • JVM 参数有变化——某些 Java 8 时代的参数被废除

三、原生镜像:启动速度的革命

Spring Boot 3 内置 GraalVM 原生镜像支持——把 JVM 应用编译成单个原生二进制:

1
2
./mvnw native:compile
./target/myapp    # 启动!

性能对比

标准 JVM原生镜像
启动时间5-30 秒30-100ms
内存占用200-500 MB30-80 MB
峰值性能高(JIT 优化)中(AOT 编译)
编译时间秒级几分钟
镜像体积JAR + JDK单二进制

适用场景

  • Serverless / FaaS——冷启动毫秒级,函数计算成本大降
  • CLI 工具
  • K8s 短生命周期 Pod
  • 资源受限环境

不适合

  • 峰值性能敏感——AOT 编译没 JIT 优化空间
  • 大量动态特性(反射、动态代理)——需要额外配置元数据
  • 依赖很多的项目——编译时间长得受不了

GraalVM 是杀手锏但不是银弹——多数业务系统暂时不需要


四、Observability 一等公民

Spring Boot 3 把可观测性提到了前所未有的高度——内置 Micrometer Observation API

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
@Bean
public ObservedAspect observedAspect(ObservationRegistry registry) {
    return new ObservedAspect(registry);
}

@Service
public class OrderService {
    @Observed(name = "order.create")
    public Order create(OrderDTO dto) {
        // 自动产生 metrics + traces + logs
    }
}

@Observed 自动产出:

  • Metrics:Prometheus 抓取
  • Traces:OpenTelemetry 上报到 Tempo/Jaeger
  • Logs:结构化日志带 trace_id

统一的 Observability 模型——以前要分别配 Micrometer + Sleuth + 自定义 logger,现在一个注解搞定。


五、HTTP Interface:声明式 HTTP 客户端

Spring 6 引入声明式 HTTP 客户端——类似 Feign 但内置:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
public interface UserClient {
    @GetExchange("/users/{id}")
    User getById(@PathVariable Long id);

    @PostExchange("/users")
    User create(@RequestBody UserDTO dto);
}

@Bean
public UserClient userClient(WebClient.Builder builder) {
    HttpServiceProxyFactory factory = HttpServiceProxyFactory
        .builderFor(WebClientAdapter.create(builder.baseUrl("https://api.com").build()))
        .build();
    return factory.createClient(UserClient.class);
}

不需要再引 Feign——官方原生支持


六、Problem Details (RFC 7807)

错误响应标准化——返回 application/problem+json

1
2
3
4
5
6
7
{
    "type": "https://example.com/probs/insufficient-balance",
    "title": "Insufficient balance",
    "status": 400,
    "detail": "Balance is 100, required 500",
    "instance": "/orders/12345"
}
1
2
3
4
5
6
@ExceptionHandler(InsufficientBalanceException.class)
public ProblemDetail handle(InsufficientBalanceException e) {
    ProblemDetail pd = ProblemDetail.forStatusAndDetail(BAD_REQUEST, e.getMessage());
    pd.setType(URI.create("https://example.com/probs/insufficient-balance"));
    return pd;
}

业内标准——前端能用统一姿势处理。


七、虚拟线程(Spring Boot 3.2+)

JDK 21 GA 了虚拟线程——Spring Boot 3.2+ 一键启用:

1
2
3
4
spring:
  threads:
    virtual:
      enabled: true

效果:

  • Tomcat 每个请求一个虚拟线程
  • 阻塞 IO 不再占用 OS 线程
  • 传统 MVC 风格代码 + 虚拟线程 = WebFlux 的吞吐

很多人会问"还要不要 WebFlux?"——虚拟线程让传统 MVC 代码用接近 WebFlux 的吞吐量服务高并发,且没学习曲线。WebFlux 的位置开始变窄。


八、其他变化清单

  • 删除 Java 8 / 11 支持
  • 删除 Spring MVC 老的 path matcher(默认走 PathPattern)
  • 新的 PropertyResolver
  • CRaC(Coordinated Restore at Checkpoint):JVM 状态快照恢复,再降启动时间
  • HTTP/2 H2C 支持改进
  • AOT 编译预处理
  • 更好的 SQL DSL(Spring Data 改进)

九、升级实战清单

评估期

  • 列出所有依赖,确认全部有 Spring Boot 3 / Jakarta 兼容版本
  • 确认 Java 17+ 在所有环境(dev、test、prod、CI)可用
  • 评估 javax → jakarta 替换工作量
  • 检查是否用了将被废弃的 API(如 WebSecurityConfigurerAdapter)

升级期

  1. 升 JDK 到 17(独立做,验证业务正常)
  2. 批量替换 javax → jakarta(IDE 工具或 OpenRewrite)
  3. 升 Spring Boot 3.0 → 3.x 最新版
  4. 升所有第三方依赖到 Jakarta 兼容版
  5. 修编译错误 + 测试
  6. Spring Security 改为新 SecurityFilterChain 写法
  7. 开启 Observability 替换老的 Sleuth

验证期

  • 全量回归测试
  • 性能基准比对(启动时间、内存、QPS)
  • 灰度发布

迁移工具


十、什么场景该升 / 什么场景缓一缓

✅ 应该升

  • 新项目——直接用 3.x,不要从 2.x 起步
  • JDK 已经在 17+——升级成本最小
  • 想用虚拟线程 / 原生镜像
  • Spring Boot 2.7 已无 OSS 支持(OSS 支持已于 2023 年 11 月结束,商业扩展支持也已于 2025 年 8 月结束)

⏳ 缓一缓

  • 依赖中有大量未升级的 javax 库
  • JDK 还卡在 8/11 升不上去
  • 业务系统稳定,没有强需求
  • 团队没人有时间做迁移测试

绝大多数项目应该启动迁移——Spring Boot 2.7 的 OSS 支持已于 2023 年 11 月结束,商业扩展支持也已于 2025 年 8 月结束,再不升就完全没有安全更新了。


十一、Spring Boot 2 → 3 的几个真实坑

1. JPA 用了 javax.persistence.GenerationType

全局替换 import。

2. Spring Security 配置类

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
// 2.x
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception { ... }
}

// 3.x
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    return http...build();
}

WebSecurityConfigurerAdapter 在 3.x 完全删除——所有项目都要重写 Security 配置

3. SwaggerUI(springdoc-openapi)

要从 1.x 升 2.x——配置完全重写。

4. Spring Cloud 版本对应

Spring Boot 3 不能用 Spring Cloud 2021.0(仍是 javax)。对应关系按 Boot 小版本严格区分

Spring BootSpring Cloud
3.0.x / 3.1.x2022.0.x(Kilburn)
3.2.x2023.0.x(Leyton)
3.3.x / 3.4.x2023.0.x 或 2024.0.x(Moorgate)
3.5.x2025.0.x(Northfields)

踩坑提醒:跨大版本配错(如 Boot 3.4+ 配 2022.0.x)会出现 starter 缺失、CVE 不修等问题。升 Boot 时务必参照 Spring Cloud Supported Versions 同步升 Cloud。

5. MyBatis-Plus

需要 3.5.3+——更老的版本不兼容 Spring Boot 3。

6. Lombok

要 1.18.24+——老版本可能编译不过。


小结

把全文压一句:

Spring Boot 3 是 Spring 生态进入 Jakarta + Java 17 + 原生镜像 + Observability 时代的入场券——不是小升级,是范式转移。

工程实践:

  1. 新项目优先用 3.x
  2. 老项目要规划迁移——拖到 2.7 EOL 就被动了
  3. Java 17+ 是基线,不可回避
  4. OpenRewrite 自动迁移省掉 80% 体力活
  5. 虚拟线程让传统 MVC 写法逼近 WebFlux 吞吐

升 Spring Boot 3 不是"为了升而升"——是 Java 服务端走向下一个十年的必经之路。

使用 Hugo 构建
主题 StackJimmy 设计