1、前言

1.1 版本选择

组件 推荐版本
JDK 17+ (LTS)
Maven 3.8.5+ / 最佳 3.9.0+
Spring Boot 最新维护版 3.5.0
spring-boot-maven-plugin 3.1.0+
maven-compiler-plugin 3.11.0

推荐配置 JDK 17 和 Spring Boot 3.5.0 (LTS)

根据官网spring-boot版本相关信息,选择合适的版本

1.2 参考资料

1.3 建议

  • 可将springboot升级到2.7.18(2.x系列最高版本),支持jdk17,实现逐步升级至spring-boot3;

本次直接将springboot升级到3.5(3.X最后一个版本)

2、升级准备

2.1 检查清单

检查项 要求 验证方式
JDK版本 17+ java -version
Maven版本 3.8.5+ (推荐3.9.0+) mvn -v
IDE支持 IntelliJ 2023.3+ -
构建工具插件 兼容JDK 17 检查pom.xml/build.gradle
代码仓库状态 无未提交修改 git status

2.2 备份

  1. 代码备份

    git tag vspringboot2.x-backup
    git push origin vspringboot2.x-backup
    
  2. 数据库备份

    mysqldump -u [user] -p[password] [database] > backup_$(date +%Y%m%d).sql
    
  3. 配置文件备份

    cp -r config/ config_backup_$(date +%Y%m%d)/
    

3、升级步骤

3.1 JDK调整

3.1.1 pom调整
  • 调整maven项目:<maven.compiler.source> 和 <maven.compiler.target> 至 17

    <!-- 配置默认编译jdk版本 -->
    <properties>
      	<!-- 配置源代码的 Java 语言版本 -->
        <maven.compiler.source>17</maven.compiler.source>
      	<!-- 配置生成的字节码(.class 文件)的目标版本 -->
        <maven.compiler.target>17</maven.compiler.target>
      	<!-- 配置使用特定版本的 javac编译器 -->
        <maven.compiler.compilerVersion>17</maven.compiler.compilerVersion>
    </properties>
    
    <!-- 显示的配置编译jdk版本 -->
    <properties>
      	<java.version>17</java.version>
    </properties>
    
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.11.0</version> <!-- 兼容版本 8 <= jdk<=21 -->
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>
    
3.1.2 javax到jakarta迁移

调整代码中javax包的坐标:

原javax 新 jakarta
javax.persistence.* jakarta.persistence.*
javax.faces.* jakarta.faces.*
javax.ejb.* jakarta.ejb.*
javax.servlet.* jakarta.servlet.*
javax.servlet.jsp.* jakarta.servlet.jsp.*
javax.websocket.* jakarta.websocket.*
javax.naming.* jakarta.naming.*
javax.sql.* jakarta.sql.*
javax.transaction.* jakarta.transaction.*
javax.validation.* jakarta.validation.*
javax.xml.* jakarta.xml (需要单独引入依赖)
javax.annotation.* jakarta.annotation.*
3.1.3 启动命令调整
java \
  # 基础内存配置(日志中显示堆和元空间信息)
  -Xms1g -Xmx1g \                         # 固定堆大小(GC日志显示初始/最大堆)
  -XX:MetaspaceSize=256m \                # 元空间初始(日志记录扩容事件)
  -XX:MaxMetaspaceSize=512m \             # 元空间上限(OOM时记录泄漏情况);JDK17对于类信息有优化,不用配置太高;如果类较多,可适当调整大小

  # -------------------------垃圾回收器---------------------------------#
  # G1垃圾回收器配置(GC日志核心参数)平衡吞吐与延迟
  -XX:+UseG1GC \                           # 启用G1(日志标记GC策略)默认值
  -XX:MaxGCPauseMillis=200 \               # 目标停顿(日志记录实际停顿时间)
  -XX:G1HeapRegionSize=4m \                # Region大小(堆布局日志可见)
  -XX:InitiatingHeapOccupancyPercent=45 \  # MixedGC触发阈值(日志显示触发时机)
  -XX:+G1PrintHeapRegions \                # 打印Region详情(增强GC日志)
  
  # --------------------垃圾回收器二、ZGC--------------------------------#
  # ZGC(超低延迟场景)
  -XX:+UseZGC \                        # 启用ZGC(需JDK17+)
  -XX:ConcGCThreads=2 \                # 并发线程数
  -XX:ZCollectionInterval=30 \         # 每30秒强制GC检查
  -XX:+ZProactive                      # 启用主动回收(JDK17优化项)
  # --------------------------垃圾回收器--------------------------------#

  # 线程配置(GC日志中显示线程使用)
  -XX:ParallelGCThreads=8 \               # 并行线程数(日志中显示线程数)
  -XX:ConcGCThreads=2 \                   # 并发线程数(标记阶段日志可见)

  # 诊断配置(独立日志文件)
  -XX:+HeapDumpOnOutOfMemoryError \        # OOM转储(路径记录到日志)
  -XX:HeapDumpPath=/var/log/heapdump.hprof \

  # 结构化日志配置(按时间和大小轮转)
  -Xlog:gc*,safepoint*:file=gc-%t.log::filesize=100M,filecount=5 \  # 核心GC日志
  -Xlog:async*=debug:async.log \           # 异步事件日志
  -Xlog:os*=info:os.log \                  # 操作系统交互日志

  # 容器化支持(启动日志显示适配情况)- 使用docker容器部署可添加
  -XX:+UseContainerSupport \               # 容器内存适配(日志确认限制值)
  -XX:MaxRAMPercentage=80.0 \              # 容器内存占比

  # 反射兼容性(模块系统日志会记录告警)
  --add-opens java.base/java.lang=ALL-UNNAMED \
  --add-opens java.base/java.util=ALL-UNNAMED \

  -jar app.jar
3.1.4 可能遇到的问题
sun.misc.BASE64Decoder找不到符号
  • 官网声明从JDK 1.8开始,就提供了java.util.Base64.Decoder和java.util.Base64.Encoder的JDK公共API,可代替sun.misc.BASE64Decodersun.misc.BASE64Encoder的JDK内部API,调整代码如下
/**
     * BASE64Encoder 加密
     * 
     * @param data
     *            要加密的数据
     * @return 加密后的字符串
     */
    public static String encryptBASE64(byte[] data) {
        // BASE64Encoder encoder = new BASE64Encoder();
        // String encode = encoder.encode(data);
        // 从JKD 9开始rt.jar包已废除,从JDK 1.8开始使用java.util.Base64.Encoder
        Encoder encoder = Base64.getEncoder();
        String encode = encoder.encodeToString(data);
        return encode;
    }
    /**
     * BASE64Decoder 解密
     * 
     * @param data
     *            要解密的字符串
     * @return 解密后的byte[]
     * @throws Exception
     */
    public static byte[] decryptBASE64(String data) throws Exception {
        // BASE64Decoder decoder = new BASE64Decoder();
        // byte[] buffer = decoder.decodeBuffer(data);
        // 从JKD 9开始rt.jar包已废除,从JDK 1.8开始使用java.util.Base64.Decoder
        Decoder decoder = Base64.getDecoder();
        byte[] buffer = decoder.decode(data);
        return buffer;
    }

程序包 com.sun.media.sound 不可见
  • JDK 11中完全移除,因为 ”Oracle/Sun的私有实现,不属于Java标准API(javax.*java.*
  • 调整建议:使用标准的**javax.sound.sampled**,如下:
  // WaveFileReader reader = new WaveFileReader();
  // AudioInputStream audioIn = reader.getAudioInputStream(new ByteArrayInputStream(data));
	// 使用jdk标准:javax.sound.sampled.AudioSystem 读取WAV文件
	AudioInputStream audioIn = AudioSystem.getAudioInputStream(new File("input.wav"));

	// WaveFileWriter writer = new WaveFileWriter();
  // writer.write(convertedIn, AudioFileFormat.Type.WAVE, file);
  // 使用jdk标准:javax.sound.sampled.AudioSystem 写入wav文件
  AudioSystem.write(convertedIn, AudioFileFormat.Type.WAVE, file);
程序包javafx.util.converter不存在
  • JavaFX 中的一个工具包,主要用于数据类型转换,特别是在 UI 控件(如 ChoiceBoxTableView 等)中实现对象与字符串之间的双向转换。,从JDK 11开始被分离出标准JDK,需手动引入依赖;解决方式如下

    --module-path /path/to/javafx-sdk/lib \
    --add-modules=javafx.controls,javafx.fxml \
    
    • 方式二:手动引入相关模块的依赖
    <!-- Maven示例 -->
    <dependency>
        <groupId>org.openjfx</groupId>
        <artifactId>javafx-controls</artifactId>
        <version>21.0.2</version> <!-- 替换为实际版本 -->
    </dependency>
    <dependency>
        <groupId>org.openjfx</groupId>
        <artifactId>javafx-fxml</artifactId>
        <version>21.0.2</version>
    </dependency>
    
程序包sun.management.resources不存在
  • 支持 Java 平台的管理接口,特别是与监控和管理相关的本地化资源;解决方式如下:

    • 使用标准的 java.lang.management,长期兼容
    RuntimeMXBean runtimeBean = ManagementFactory.getRuntimeMXBean();
    System.out.println("JVM Uptime: " + runtimeBean.getUptime() + "ms");
    
程序包org.omg.CORBA不存在
  • CORBA 是一种面向对象的分布式计算模型,允许不同平台上运行的应用程序通过网络进行交互
    • 项目中如果没有使用,只是引用删除即可;
    • 如果存在引用,需要调整代码,使用grpc等方案进行替代;

3.2 修改springboot版本(Maven项目)

3.2.1 pom调整
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.5.0</version>
</parent>

<!-- 如果项目中用到了bom,进行管理管理,版本也需要调整为3.5.0 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-dependencies</artifactId>
    <version>3.5.0</version>
    <type>pom</type>
    <scope>import</scope>
</dependency>

3.3 依赖库组件

3.3.1 Slf4j – logback
  • 推送使用logback实现,不使用log4j;springboot3默认的logback组件版本是:1.5.18
    在这里插入图片描述
<!-- springboot2.7.18支持的最高版本-->
<!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-classic -->
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.2.13</version>
    <scope>compile</scope>
</dependency>


<!-- 可以不指定版本,springboot3.5 默认的版本就是1.5.18-->
<!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-classic -->
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.5.18</version>
    <scope>compile</scope>
</dependency>

<!-- 可以不指定版本,springboot3.5 默认的版本就是1.5.18-->
<!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-core -->
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-core</artifactId>
    <version>1.5.18</version>
</dependency>
3.3.2 mysql-connect-java
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>${mysql-connector-java.version}</version>
</dependency>

<!-- 调整对应依赖 -->
<!-- https://mvnrepository.com/artifact/com.mysql/mysql-connector-j 截止2025年7月最新版本-->
<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
    <version>9.3.0</version> 
</dependency>
3.3.3 mybatis-plus
<!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-spring-boot3-starter 截止2025年7月22日最新版本-->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-spring-boot3-starter</artifactId>
    <version>3.5.12</version>
</dependency>
  • 注意:组件坐标一定是:mybatis-plus-spring-boot3-starter 而不能是: mybatis-plus-boot-starter 是针对 spring-boot2.x & jdk8
<!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter 截止2025年7月22日最新版本-->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.12</version>
</dependency>
  • 如果引入上面的,启动会出现:Invalid value type for attribute ‘factoryBeanObjectType‘: java.lang.String
3.3.4 httpclient
<!-- https://mvnrepository.com/artifact/commons-httpclient/commons-httpclient -->
<dependency>
    <groupId>commons-httpclient</groupId>
    <artifactId>commons-httpclient</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
</dependency>

<!-- 上面两个依赖组件都:建议调整为httpclient5,协议和性能方面都有较大优化 -->
<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents.client5/httpclient5 截止2025年7月最新版本 -->
<dependency>
    <groupId>org.apache.httpcomponents.client5</groupId>
    <artifactId>httpclient5</artifactId>
    <version>5.5</version>
</dependency>
3.3.5 jedis & redisson & lettuce
<!-- 如果之前项目中使用的是jedis:建议升级jedis版本,6.0.0 是截止2025年7月20日 最新版本->
<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>6.0.0</version> 
</dependency>

<!-- 新项目如果想要redis,则客户端推荐使用默认的lettuce->
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-redis -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

<!-- redisson推荐使用最新版本 -->
<!-- https://mvnrepository.com/artifact/org.redisson/redisson  截止2025年7月20日 最新版本-->
<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson</artifactId>
    <version>3.50.0</version>
</dependency>
  • spring-boot-starter-data-redis 中默认的lettuce版本:6.5.5.RELEASE
    在这里插入图片描述
3.3.6 common-lang(工具类库)
<!-- https://mvnrepository.com/artifact/commons-lang/commons-lang -->
<dependency>
    <groupId>commons-lang</groupId>
    <artifactId>commons-lang</artifactId>
</dependency>


<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 截止2025年7月20日 最新版本-->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.18.0</version>
</dependency>
3.3.7 fastjson
<!-- 推荐使用fastjson2: JSON parser + JSON generator-->
<!-- https://mvnrepository.com/artifact/com.alibaba.fastjson2/fastjson2 -->
<dependency>
    <groupId>com.alibaba.fastjson2</groupId>
    <artifactId>fastjson2</artifactId>
    <version>2.0.53</version>
</dependency>
3.3.8 lombok
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok 截止2025年7月20日 最新版本-->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.38</version>
</dependency>
3.3.9 PaheHelper(刚支持mybatis3.x版本、springboot3)
<!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper-spring-boot-starter 截止2025年7月20日 最新版本-->
<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper-spring-boot-starter</artifactId>
    <version>2.1.1</version>
</dependency>

在这里插入图片描述

3.3.10 web容器
  • spring-boot-web自带的是tomcat容器,对应版本如下:10.1.42(协议优化、NIO连接优化,性能比9.x更好)
    在这里插入图片描述
  • 若使用undertow,spring-boot3.5版本中 spring-boot-starter-undertow 对应版本是 3.5.3,
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
      <!-- 使用undertow一定要排查web自带的tomcat的包 -->
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </exclusion>
    </exclusions>
</dependency>

<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-undertow 3.5.3 截止2025年7月20日 最新版本- -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-undertow</artifactId>
</dependency>

3.4 其他api调整

3.4.1 bean注入异常

装配方式: spring.factories 需要改成AutoConfiguration.imports

  • spring-boot 3.x版本前使用的是 src/main/resources/META-INF/spring.factories 自动装配方式;
  • spring-boot 3.x版本 改成了 src/main/resources/META-INF**/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports** 自动装配方式

spring-boot 3.x版本前实现方式:

  • src/main/resources/META-INF/spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  com.panape.springbootupgrade.config.CustomerAutoConfig

spring-boot 3.x版本需要调整为:

  • src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
com.panape.springbootupgrade.config.CustomerAutoConfig

3.5 配置文件调整

主要列出了如下变更:

spring-boot2.x spring-boot3.x
spring.resources.cache.period spring.web.resources.cache.period
spring.redis spring.data.redis
spring.web.resources.chain.compressed spring.resources.chain.compressed
spring.resources.chain.compressed 已删除
server.max-http-header-size server.max-http-request-header-size

3.6 其他调整

3.6.1 插件git-commit-id-plugin调整
  • git-commit-id-plugin 坐标已更改:
 <plugin>
    <groupId>pl.project13.maven</groupId>
    <artifactId>git-commit-id-plugin</artifactId>
    <version>4.0.0</version>
</plugin>

<plugin>
    <groupId>io.github.git-commit-id</groupId>
    <artifactId>git-commit-id-maven-plugin</artifactId>
    <version>9.0.2</version>
</plugin>
3.6.2 Spring MVC 和 WebFlux URL 匹配更改
  • 从 Spring Framework 6.0 开始,尾部斜杠匹配配置选项已被弃用,其默认值设置为false

    • 之前版本以下控制器将同时匹配“GET /some/greeting”和“GET /some/greeting/”:

      @RestController
      public class MyController {
      
          @GetMapping("/some/greeting")
          public String greeting() {
            return "Hello";
          }
      }
      
    • 新版本:“GET /some/greeting/” 不在匹配

3.6.3 server.max-http-header-size
  • 限制内嵌容器请求头大小,改配置项已被启用,调整为:server.max-http-request-header-size
3.6.4 Actuator端点脱敏
  • 在以前的版本中,Spring 会自动屏蔽端点 /env/configprops 上的敏感 key 值,这些端点会显示配置属性和环境变量等敏感信息。在此版本中,Spring 更改了方法,默认情况下更加安全。
  • 现在,它不再只屏蔽某些 key 值,而是默认屏蔽所有 key 值。我们可以通过设置 management.endpoint.env.show-values(适用于 /env 端点)或 management.endpoint.configprops.show-values(适用于 /configprops 端点)的属性值来更改这一配置。可选值如下:
    • NEVER:不显示值
    • ALWAYS:显示所有值。
    • WHEN_AUTHORIZED:如果用户已获授权,则会显示所有值。对于 JMX,所有用户都已授权。对于 HTTP,只有特定角色可以访问数据。
Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐