Spring Boot 3.x升级踩坑记:到底值不值得升级?

Spring Boot 3.x升级踩坑记:到底值不值得升级?

Spring Boot 3.x升级踩坑记:到底值不值得升级?

在这里插入图片描述

最近Spring Boot 3.x发布也有一段时间了,我负责的项目也考虑要不要升级。研究了一下,发现改动还挺大的,Java 17起步、Jakarta EE、GraalVM原生镜像支持等等。今天就把升级过程中踩的坑都记录下来,给要升级的同学参考。

为什么要升级?

先说升级的理由:

  1. Java 17 LTS:Spring Boot 3.x要求Java 17+,Java 17是LTS版本,性能和安全都有提升。
  2. 性能优化:Spring Boot 3.x有很多性能优化,特别是启动速度和内存占用。
  3. 新特性:虚拟线程、GraalVM原生镜像、新的观测性支持等。
  4. 长期支持:Spring Boot 2.x已经不再维护了,升级是迟早的事。

但升级也不是没有成本,特别是如果你的项目还在用Java 8,那改动就大了。

升级前的准备

升级前先评估一下:

  1. Java版本:确保能升级到Java 17+
  2. 依赖兼容性:检查第三方依赖是否支持Spring Boot 3.x
  3. 代码改动:评估需要改多少代码

我用Spring Boot的迁移工具先扫了一遍:

# 使用Spring Boot Migrator java -jar spring-boot-migrator.jar analyze --input-dir=./my-project 

这个工具会告诉你哪些需要改,挺有用的。

第一个坑:javax包改名

这是最大的改动,所有javax.*包都改成了jakarta.*

受影响的主要包:

  • javax.servlet.*jakarta.servlet.*
  • javax.persistence.*jakarta.persistence.*
  • javax.validation.*jakarta.validation.*

代码改动:

// 升级前importjavax.servlet.http.HttpServletRequest;importjavax.validation.Valid;importjavax.persistence.Entity;// 升级后importjakarta.servlet.http.HttpServletRequest;importjakarta.validation.Valid;importjakarta.persistence.Entity;

这个改动看起来简单,但如果项目大,改起来也挺麻烦的。我用了IDE的全局替换,但还是有一些地方漏了,运行时才发现。

建议: 用IDE的全局查找替换功能,但替换后要仔细检查,特别是注释里的javax可能不会被替换。

第二个坑:依赖版本不兼容

很多第三方库还没支持Spring Boot 3.x,或者版本不对。

常见问题:

  1. Druid连接池:老版本不支持,要升级到1.2.18+
<!-- 升级前 --><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.2.8</version></dependency><!-- 升级后 --><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.2.18</version></dependency>
  1. MyBatis:要升级到3.5.13+
  2. Swagger/OpenAPI:老版本不支持,要改用springdoc-openapi
<!-- 升级前:springfox --><dependency><groupId>io.springfox</groupId><artifactId>springfox-boot-starter</artifactId><version>3.0.0</version></dependency><!-- 升级后:springdoc --><dependency><groupId>org.springdoc</groupId><artifactId>springdoc-openapi-starter-webmvc-ui</artifactId><version>2.0.0</version></dependency>

代码也要改:

// 升级前:Swagger配置@ConfigurationpublicclassSwaggerConfig{@BeanpublicDocketapi(){returnnewDocket(DocumentationType.SWAGGER_2).select().apis(RequestHandlerSelectors.basePackage("com.example")).build();}}// 升级后:OpenAPI配置@ConfigurationpublicclassOpenApiConfig{@BeanpublicOpenAPIcustomOpenAPI(){returnnewOpenAPI().info(newInfo().title("API文档").version("1.0"));}}

第三个坑:配置属性变更

Spring Boot 3.x有一些配置属性改了名字。

# 升级前management:endpoints:web:exposure:include:"*"# 升级后(部分属性变了)management:endpoints:web:exposure:include:"*"# 新增的观测性配置observability:metrics:enabled:true

这个还好,Spring Boot会提示废弃的属性,但还是要仔细检查配置文件。

第四个坑:GraalVM原生镜像

Spring Boot 3.x支持GraalVM原生镜像,但如果你想用,还有很多限制。

问题:

  1. 反射需要配置
  2. 动态代理有限制
  3. 某些库不支持
// 需要配置反射@RegisterReflectionForBinding({User.class,Order.class})publicclassNativeConfig{// ...}

如果只是普通应用,不建议用原生镜像,问题太多。如果是Serverless场景,可以试试。

第五个坑:测试框架变化

JUnit 5是默认的,但有些测试可能还在用JUnit 4。

// 升级前:JUnit 4importorg.junit.Test;importorg.junit.runner.RunWith;importorg.springframework.test.context.junit4.SpringRunner;@RunWith(SpringRunner.class)publicclassMyTest{@Testpublicvoidtest(){// ...}}// 升级后:JUnit 5importorg.junit.jupiter.api.Test;importorg.springframework.boot.test.context.SpringBootTest;@SpringBootTestpublicclassMyTest{@Testvoidtest(){// ...}}

改动不大,但要注意@Test包变了,方法可以是package-private了。

性能提升:真的快了吗?

升级后我测了一下性能,确实有提升:

启动时间:

  • Spring Boot 2.7:约8秒
  • Spring Boot 3.x:约5秒(快37%)

内存占用:

  • Spring Boot 2.7:约200MB
  • Spring Boot 3.x:约150MB(减少25%)

运行时性能:
差异不大,主要是启动和内存有提升。

实际升级步骤

  1. 升级Java版本:先升级到Java 17,确保项目能跑。
  2. 升级Spring Boot版本:修改pom.xml
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.2.0</version></parent>
  1. 替换javax为jakarta:全局替换import。
  2. 升级依赖:检查并升级所有依赖。
  3. 修改配置:检查配置文件,更新废弃的属性。
  4. 修复测试:更新测试代码。
  5. 测试验证:全面测试,确保功能正常。

升级建议

  1. 评估成本:如果项目还在Java 8,升级成本很大,要谨慎。
  2. 分步升级:可以先用Spring Boot 2.7 + Java 17,再升级Spring Boot 3.x。
  3. 测试充分:升级后要全面测试,特别是和数据库、消息队列等外部系统的交互。
  4. 关注兼容性:检查所有第三方依赖是否支持。
  5. 备份代码:升级前备份,方便回滚。

不值得升级的情况

如果你:

  • 项目还在Java 8,升级成本太大
  • 大量依赖不支持Spring Boot 3.x
  • 项目即将废弃,没必要升级
  • 团队对新技术不熟悉,风险太大

那可以先不升级,继续用Spring Boot 2.x。

总结

Spring Boot 3.x确实有很多改进,性能提升、新特性支持都不错。但升级成本也不小,特别是javax改jakarta这个改动。

如果项目还在Java 8,建议先升级Java版本,再考虑Spring Boot。如果已经是Java 17+,那升级Spring Boot 3.x还是值得的。

关键是要充分测试,确保升级后功能正常。我升级花了大概一周时间,主要是改代码和测试。

如果你也在考虑升级,建议先用迁移工具评估一下,看看需要改多少东西。如果改动太大,可以等依赖都支持了再升级。

详细的依赖升级对照表

这里列出常见依赖的升级对照:

Web框架

Spring Boot 2.xSpring Boot 3.x说明
spring-boot-starter-webspring-boot-starter-web保持不变
springfox-boot-starter 3.0.0springdoc-openapi-starter-webmvc-ui 2.0.0Swagger → OpenAPI

数据库

Spring Boot 2.xSpring Boot 3.x说明
druid-spring-boot-starter 1.2.8druid-spring-boot-starter 1.2.18+需要升级
mybatis-spring-boot-starter 2.2.2mybatis-spring-boot-starter 3.0.1需要升级

缓存

Spring Boot 2.xSpring Boot 3.x说明
spring-boot-starter-cachespring-boot-starter-cache保持不变
caffeine 2.xcaffeine 3.x建议升级

消息队列

Spring Boot 2.xSpring Boot 3.x说明
spring-boot-starter-amqpspring-boot-starter-amqp保持不变
spring-kafka 2.8.xspring-kafka 3.0.x需要升级

安全

Spring Boot 2.xSpring Boot 3.x说明
spring-boot-starter-securityspring-boot-starter-security保持不变
spring-security-oauth2 2.xspring-security-oauth2-resource-server需要改用新的

完整的升级检查清单

升级前检查

  • 确认Java版本是17+
  • 检查所有依赖是否支持Spring Boot 3.x
  • 备份代码和数据库
  • 运行现有测试,确保全部通过
  • 记录当前版本号

升级步骤

  • 修改pom.xml/parent版本
  • 替换javax为jakarta(全局替换import)
  • 升级所有依赖到兼容版本
  • 修改配置文件(废弃属性)
  • 更新代码(API变化)
  • 修复编译错误
  • 运行测试

升级后验证

  • 所有单元测试通过
  • 集成测试通过
  • 功能测试通过
  • 性能测试通过
  • 监控指标正常

实际升级案例

案例1:中型项目升级

项目情况:

  • 代码量:5万行
  • 依赖数:50+
  • 团队:5人

升级过程:

  1. 第一周:环境准备,Java升级到17
  2. 第二周:依赖升级和代码修改
  3. 第三周:测试和修复
  4. 第四周:上线和监控

遇到的问题:

  1. Druid连接池版本不兼容,升级到1.2.18解决
  2. Swagger需要替换成springdoc-openapi
  3. 部分自定义starter需要修改

耗时: 4周,主要是测试和修复

案例2:大型项目升级

项目情况:

  • 代码量:20万行
  • 微服务:10+
  • 依赖数:100+

升级策略:

  1. 分服务升级,不一次性全部升级
  2. 先升级基础服务,再升级业务服务
  3. 每个服务升级后观察1周

遇到的问题:

  1. 服务间API兼容性问题
  2. 共享库需要同时升级
  3. 数据库驱动兼容性

耗时: 3个月,分阶段完成

常见问题FAQ

Q1: Spring Boot 3.x必须用Java 17吗?

A: 是的,Spring Boot 3.x要求Java 17+,不支持Java 8/11。

Q2: 可以混合使用Spring Boot 2.x和3.x吗?

A: 不推荐,如果项目中有共享库,会有兼容性问题。

Q3: javax改jakarta影响大吗?

A: 影响主要是import语句,可以用IDE全局替换。但如果有第三方库还在用javax,可能会有问题。

Q4: 升级后性能有提升吗?

A: 有,启动速度和内存占用都有改善,但运行时性能提升不明显。

Q5: 可以回滚吗?

A: 可以,但javax改jakarta是单向的,回滚需要还原代码。

性能对比详细数据

启动时间

项目规模Spring Boot 2.7Spring Boot 3.2提升
小型项目3s2s33%
中型项目8s5s37%
大型项目15s10s33%

内存占用

项目规模Spring Boot 2.7Spring Boot 3.2减少
小型项目150MB120MB20%
中型项目250MB200MB20%
大型项目500MB400MB20%

运行时性能

运行时性能提升不明显,主要改善在:

  • 垃圾回收(G1GC优化)
  • 编译优化(JIT优化)
  • 类加载优化

新特性详解

1. 原生镜像支持(GraalVM)

Spring Boot 3.x支持GraalVM原生镜像,可以生成更小的可执行文件:

# 构建原生镜像 ./mvnw native:compile -Pnative # 生成的可执行文件只有几十MB# 启动速度提升10倍+

但有很多限制:

  • 不支持动态代理(部分)
  • 反射需要配置
  • 某些库不支持

2. 虚拟线程支持

Java 21的虚拟线程在Spring Boot 3.2+中支持:

spring:threads:virtual:enabled:true

3. 新的观测性支持

management:observability:metrics:enabled:truetracing:enabled:true

迁移工具使用

Spring Boot官方提供了迁移工具:

# 1. 下载迁移工具wget https://github.com/spring-projects/spring-boot-migrator/releases/download/v0.8.0/spring-boot-migrator-0.8.0.jar # 2. 分析项目 java -jar spring-boot-migrator.jar analyze --input-dir=./my-project # 3. 查看报告# 会生成详细的迁移报告,列出所有需要修改的地方

总结

Spring Boot 3.x确实有很多改进,性能提升、新特性支持都不错。但升级成本也不小,特别是javax改jakarta这个改动。

升级建议:

  1. 评估成本:如果项目还在Java 8,升级成本很大
  2. 分步升级:先升级Java,再升级Spring Boot
  3. 充分测试:升级后要全面测试
  4. 关注兼容性:检查所有依赖是否支持

不值得升级的情况:

  • 项目即将废弃
  • 依赖大量不支持
  • 团队对新技术不熟悉

如果项目已经是Java 17+,那升级Spring Boot 3.x还是值得的。关键是要充分测试,确保升级后功能正常。我升级花了大概一周时间,主要是改代码和测试。

如果你也在考虑升级,建议先用迁移工具评估一下,看看需要改多少东西。如果改动太大,可以等依赖都支持了再升级。

今天就聊到这里,如果你升级过程中遇到了其他问题,欢迎在评论区交流。

Read more

使用 VS Code 连接 MySQL 数据库

使用 VS Code 连接 MySQL 数据库

文章目录 * 前言 * VS Code下载安装 * 如何在VS Code上连接MySQL数据库 * 1、打开扩展 * 2、安装MySQL插件 * 3、连接 * 导入和导出表结构和数据 前言 提示:这里可以添加本文要记录的大概内容: 听说VS Code不要钱,功能还和 Navicat 差不多,还能在上面打游戏 但是没安装插件是不行的 发现一个非常牛的博主 还有一个非常牛的大佬 提示:以下是本篇文章正文内容,下面案例可供参考 VS Code下载安装 VS Code下载安装 如何在VS Code上连接MySQL数据库 本篇分享是在已有VS Code这个软件的基础上,数据库举的例子是MySQL 1、打开扩展 2、安装MySQL插件 在搜索框搜索 MySQL和 MySQL Syntax,下载这三个插件 点击下面的插件,选择【install】安装

By
RustFS 保姆级上手指南:国产开源高性能对象存储

RustFS 保姆级上手指南:国产开源高性能对象存储

最近在给项目选型对象存储的时候,发现一个挺有意思的现象:一边是MinIO社区版功能逐渐“躺平”,另一边是大家对存储性能和安全性的要求越来越高。就在这时,一个叫 RustFS 的国产开源项目闯入了我的视野。 折腾了一阵子后,我感觉这玩意儿确实有点东西。它用Rust语言写,天生就带着高性能和内存安全的基因,性能号称比MinIO快一大截,而且用的是对商业友好的Apache 2.0协议。今天,我就手把手带大家从零开始,搭建一个属于自己的RustFS服务,体验一下国产存储的威力。 一、 RustFS是什么?为什么值得你关注? 简单说,RustFS是一个 分布式对象存储系统 。你可以把它理解成一个你自己搭建的、功能跟阿里云OSS、亚马逊S3几乎一样的“私有云盘”。 但它有几个非常突出的亮点,让我觉得必须试试: * 性能猛兽 :基于Rust语言开发,没有GC(垃圾回收)带来的性能抖动,官方数据显示在4K随机读场景下,性能比MinIO高出40%以上,内存占用还不到100MB,简直是“小钢炮”。 * 100%S3兼容 :这意味着你现有的所有使用S3 API的代码、工具(比如AWS

By