项目升级概览
基于 公司科创项目 的实际升级经验,本文档详细记录了从 spring boot 2.7.0 升级到 spring boot 3.2.5 的完整过程。
升级时间线
- 升级前版本: spring boot 2.7.0
- 升级后版本: spring boot 3.2.5
- java 版本: 升级到 java 17
- 主要升级时间: 2025年6月
第一步:环境准备
1.1 java 环境升级
检查当前 java 版本:
java -version
安装 java 17:
# macos (使用 homebrew) brew install openjdk@17 # 或者下载官方 jdk 17 # https://www.oracle.com/java/technologies/downloads/#java17
设置 java_home:
export java_home=/library/java/javavirtualmachines/openjdk-17.jdk/contents/home export path=$java_home/bin:$path
1.2 maven 配置更新
更新 maven 编译器插件:
<plugin> <groupid>org.apache.maven.plugins</groupid> <artifactid>maven-compiler-plugin</artifactid> <version>3.11.0</version> <configuration> <source>17</source> <target>17</target> <encoding>utf-8</encoding> <release>17</release> <parameters>true</parameters> <compilerargs> <arg>--add-opens</arg> <arg>jdk.compiler/com.sun.tools.javac.processing=all-unnamed</arg> <arg>--add-opens</arg> <arg>jdk.compiler/com.sun.tools.javac.util=all-unnamed</arg> </compilerargs> </configuration> </plugin>
第二步:核心依赖升级
2.1 spring boot 版本升级
父 pom 更新:
<properties> <spring-boot.version>3.2.5</spring-boot.version> <java.version>17</java.version> </properties> <dependencymanagement> <dependencies> <dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-dependencies</artifactid> <version>${spring-boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencymanagement>
spring cloud 版本升级:
<properties> <spring-cloud.version>2022.0.4</spring-cloud.version> <spring-cloud-alibaba.version>2022.0.0.0</spring-cloud-alibaba.version> </properties>
2.2 数据库相关依赖升级
mybatis plus 升级:
<!-- 升级前 --> <dependency> <groupid>com.baomidou</groupid> <artifactid>mybatis-plus-boot-starter</artifactid> <version>3.5.2</version> </dependency> <!-- 升级后 --> <dependency> <groupid>com.baomidou</groupid> <artifactid>mybatis-plus-spring-boot3-starter</artifactid> <version>3.5.5</version> </dependency>
重要变更:
- 主键生成策略
id_worker_str
被废弃,使用assign_id
替代 selectcount
方法不再返回int
类型,现在返回long
类型
// 升级前 @tableid(type = idtype.id_worker_str) private string id; int count = usermapper.selectcount(wrapper); // 升级后 @tableid(type = idtype.assign_id) private string id; long count = usermapper.selectcount(wrapper);
动态数据源升级:
<!-- 升级前 --> <dependency> <groupid>com.baomidou</groupid> <artifactid>dynamic-datasource-spring-boot-starter</artifactid> <version>3.4.1</version> </dependency> <!-- 升级后 --> <dependency> <groupid>com.baomidou</groupid> <artifactid>dynamic-datasource-spring-boot3-starter</artifactid> <version>4.3.1</version> </dependency>
注意: 如果不升级到 4.3.1 版本,可能会出现数据源配置读取失败的错误:
failed to configure a datasource: 'url' attribute is not specified and no embedded datasource could be configured.
druid 连接池升级:
<!-- 升级前 --> <dependency> <groupid>com.alibaba</groupid> <artifactid>druid</artifactid> <version>1.2.9</version> </dependency> <!-- 升级后 --> <dependency> <groupid>com.alibaba</groupid> <artifactid>druid-spring-boot-3-starter</artifactid> <version>1.2.25</version> </dependency>
分页插件升级:
<!-- 升级前 --> <dependency> <groupid>com.github.pagehelper</groupid> <artifactid>pagehelper-spring-boot-starter</artifactid> <version>1.3.0</version> </dependency> <!-- 升级后 --> <dependency> <groupid>com.github.pagehelper</groupid> <artifactid>pagehelper-spring-boot-starter</artifactid> <version>1.3.1</version> </dependency>
shardingsphere 升级:
<!-- 升级前 --> <dependency> <groupid>io.shardingsphere</groupid> <artifactid>sharding-jdbc-spring-boot-starter</artifactid> <version>4.1.0</version> </dependency> <!-- 升级后 --> <dependency> <groupid>org.apache.shardingsphere</groupid> <artifactid>shardingsphere-jdbc-core-spring-boot-starter</artifactid> <version>5.1.0</version> </dependency>
注意: 如果不升级到 5.1.0 版本,可能读取不到数据库配置。
第三步:包名迁移 (javax → jakarta)
3.1 核心包名变更
这是升级过程中最重要的变更之一。spring boot 3 将所有的 javax.*
包迁移到 jakarta.*
。
主要变更列表:
升级前 | 升级后 |
---|---|
javax.annotation.* | jakarta.annotation.* |
javax.servlet.* | jakarta.servlet.* |
javax.persistence.* | jakarta.persistence.* |
javax.validation.* | jakarta.validation.* |
javax.transaction.* | jakarta.transaction.* |
javax.xml.* | jakarta.xml.* |
3.2 具体代码变更示例
注解变更:
// 升级前 import javax.annotation.postconstruct; import javax.annotation.resource; // 升级后 import jakarta.annotation.postconstruct; import jakarta.annotation.resource;
servlet 相关变更:
// 升级前 import javax.servlet.servlet; import javax.servlet.filter; import javax.servlet.servletregistrationbean; // 升级后 import jakarta.servlet.servlet; import jakarta.servlet.filter; import jakarta.servlet.servletregistrationbean;
druid 配置变更:
// 升级前 import com.alibaba.druid.support.http.statviewservlet; import com.alibaba.druid.support.http.webstatfilter; // 升级后 import com.alibaba.druid.support.jakarta.statviewservlet; import com.alibaba.druid.support.jakarta.webstatfilter;
3.3 批量替换脚本
可以使用以下命令批量替换包名:
# 替换 javax.annotation 为 jakarta.annotation find . -name "*.java" -exec sed -i '' 's/javax\.annotation/jakarta.annotation/g' {} \; # 替换 javax.servlet 为 jakarta.servlet find . -name "*.java" -exec sed -i '' 's/javax\.servlet/jakarta.servlet/g' {} \; # 替换 javax.persistence 为 jakarta.persistence find . -name "*.java" -exec sed -i '' 's/javax\.persistence/jakarta.persistence/g' {} \;
第四步:api 文档框架迁移
4.1 swagger 到 springdoc openapi
依赖变更:
<!-- 移除旧的 swagger 依赖 --> <!-- <dependency> <groupid>io.springfox</groupid> <artifactid>springfox-boot-starter</artifactid> <version>3.0.0</version> </dependency> <dependency> <groupid>com.github.xiaoymin</groupid> <artifactid>swagger-bootstrap-ui</artifactid> <version>1.9.6</version> </dependency> --> <!-- 添加新的 springdoc openapi 依赖 --> <dependency> <groupid>org.springdoc</groupid> <artifactid>springdoc-openapi-starter-webmvc-ui</artifactid> <version>2.8.8</version> </dependency>
注解映射表:
swagger 注解 | springdoc openapi 注解 |
---|---|
@api | @tag |
@apioperation | @operation |
@apiparam | @parameter |
@apimodel | @schema |
@apimodelproperty | @schema |
@apiresponse | @apiresponse |
@apiresponses | @apiresponses |
具体代码变更:
// 升级前 import io.swagger.annotations.api; import io.swagger.annotations.apioperation; import io.swagger.annotations.apiparam; @api(tags = "用户管理") @restcontroller public class usercontroller { @apioperation("获取用户信息") @getmapping("/user/{id}") public user getuser(@apiparam("用户id") @pathvariable string id) { return userservice.getuser(id); } } // 升级后 import io.swagger.v3.oas.annotations.tags.tag; import io.swagger.v3.oas.annotations.operation; import io.swagger.v3.oas.annotations.parameter; @tag(name = "用户管理") @restcontroller public class usercontroller { @operation(summary = "获取用户信息") @getmapping("/user/{id}") public user getuser(@parameter(description = "用户id") @pathvariable string id) { return userservice.getuser(id); } }
4.2 knife4j 升级
依赖变更:
<!-- 升级前 --> <dependency> <groupid>com.github.xiaoymin</groupid> <artifactid>knife4j-spring-boot-starter</artifactid> <version>2.0.8</version> </dependency> <!-- 升级后 --> <dependency> <groupid>com.github.xiaoymin</groupid> <artifactid>knife4j-openapi3-jakarta-spring-boot-starter</artifactid> <version>4.4.0</version> </dependency>
注意: knife4j 4.4.0 版本较高,公司私 服和阿里云镜像中可能不存在,需要添加镜像源:
<repository> <id>central</id> <name>maven central</name> <url>https://repo1.maven.org/maven2</url> </repository>
第五步:安全认证框架升级
5.1 sa-token 升级
依赖变更:
<!-- 升级前 --> <dependency> <groupid>cn.dev33</groupid> <artifactid>sa-token-spring-boot-starter</artifactid> <version>1.31.0</version> </dependency> <!-- 升级后 --> <dependency> <groupid>cn.dev33</groupid> <artifactid>sa-token-spring-boot3-starter</artifactid> <version>1.34.0</version> </dependency>
代码变更:
// 升级前 import cn.dev33.satoken.id.saidutil; public class tokenutil { public static string getinnerauthtoken() { return saidutil.gettoken(); } public static void checkinnertoken(string token) { saidutil.checktoken(token); } } // 升级后 import cn.dev33.satoken.stp.stputil; public class tokenutil { public static string getinnerauthtoken() { return stputil.gettokenvalue(); } public static void checkinnertoken(string token) { // 根据新版本api调整 // saidutil.checktoken(token); } }
5.2 shiro 升级
依赖变更:
<!-- 升级前 --> <dependency> <groupid>org.apache.shiro</groupid> <artifactid>shiro-spring-boot-starter</artifactid> <version>2.0.4</version> </dependency> <!-- 升级后 --> <dependency> <groupid>org.apache.shiro</groupid> <artifactid>shiro-jakarta-ee</artifactid> <version>2.0.4</version> </dependency>
注意: shiro-spring-boot-starter
2.0.4 不再支持 jakarta,需要使用 shiro-jakarta-ee
。
5.3 oauth2 升级
升级到 spring authorization server:
<dependency> <groupid>org.springframework.security</groupid> <artifactid>spring-security-oauth2-authorization-server</artifactid> </dependency>
注意: 授权中心需要重构,使用 spring authorization server 替换原有的 oauth2 实现。
5.4 jwt 升级
依赖变更:
<!-- 升级前 --> <dependency> <groupid>io.jsonwebtoken</groupid> <artifactid>jjwt</artifactid> <version>0.9.1</version> </dependency> <!-- 升级后 --> <dependency> <groupid>io.jsonwebtoken</groupid> <artifactid>jjwt-api</artifactid> <version>0.12.3</version> </dependency> <dependency> <groupid>io.jsonwebtoken</groupid> <artifactid>jjwt-impl</artifactid> <version>0.12.3</version> <scope>runtime</scope> </dependency> <dependency> <groupid>io.jsonwebtoken</groupid> <artifactid>jjwt-jackson</artifactid> <version>0.12.3</version> <scope>runtime</scope> </dependency>
代码变更:
// 升级前 claims claims = jwts.parser() .setsigningkey(secret) .parseclaimsjws(token) .getbody(); // 升级后 secretkey key = keys.hmacshakeyfor(tokenconstants.secret.getbytes()); jwtparser parser = jwts.parser().verifywith(key).build(); claims claims = parser.parsesignedclaims(token).getpayload();
第六步:工具库升级
6.1 常用工具库版本升级
<properties> <!-- apache commons --> <common-lang3.version>3.13.0</common-lang3.version> <commons-io.version>2.15.1</commons-io.version> <commons-text.version>1.11.0</commons-text.version> <!-- json 处理 --> <fastjson.version>2.0.43</fastjson.version> <jackson.version>2.15.3</jackson.version> <!-- 其他工具库 --> <hutool-all.version>5.8.24</hutool-all.version> <guava.version>33.0.0-jre</guava.version> <okhttp3.version>4.12.0</okhttp3.version> <lombok.version>1.18.30</lombok.version> </properties>
6.2 apache poi 升级
依赖变更:
<!-- 升级前 --> <poi.version>4.1.2</poi.version> <!-- 升级后 --> <poi.version>5.2.3</poi.version>
6.3 包名变更处理
apache commons lang:
// 升级前 import org.apache.commons.lang.stringutils; // 升级后 import org.apache.commons.lang3.stringutils;
6.4 base64 编码解码变更
问题: cannot resolve symbol 'base64decoder'
解决方案: 使用标准的 java.util.base64
替代
// 升级前(解码) static base64decoder decoder = new base64decoder(); byte[] b = decoder.decodebuffer(regreplacebase64(imgstr)); // 升级后(解码) byte[] b = base64.getdecoder().decode(regreplacebase64(imgstr)); // 升级前(编码) base64encoder encode = new base64encoder(); string s = encode.encode(data); // 升级后(编码) string s = base64.getencoder().encodetostring(data);
6.5 xpath 包名变更
问题: package 'com.sun.org.apache.xpath.internal.operations' is declared in module 'java.xml', which does not export it to the unnamed module
解决方案: 使用 javax.xml.xpath
替代
// 升级前 import com.sun.org.apache.xpath.internal.operations.string; // 升级后 import javax.xml.xpath.xpath; import javax.xml.xpath.xpathfactory;
第七步:配置类调整
7.1 动态数据源配置调整
配置类变更:
// 升级前 @configuration public class mybatisplusconfig { @primary @bean(name = "datasourcesystem") public datasource datasourceone(dynamicdatasourceproperties properties) throws sqlexception, ioexception, urisyntaxexception { datasource datasource = dynamicdatasource(properties); initdynamicdatasource(datasource, properties); return datasource; } } // 升级后 @configuration @enableconfigurationproperties(dynamicdatasourceproperties.class) public class mybatisplusconfig { private final dynamicdatasourceproperties dynamicdatasourceproperties; public mybatisplusconfig(dynamicdatasourceproperties dynamicdatasourceproperties) { this.dynamicdatasourceproperties = dynamicdatasourceproperties; } @primary @bean public dynamicdatasourceproperties primarydynamicdatasourceproperties() { return dynamicdatasourceproperties; } @primary @bean(name = "datasourcesystem") public datasource datasourceone() throws sqlexception, ioexception, urisyntaxexception { datasource datasource = dynamicdatasource(dynamicdatasourceproperties); initdynamicdatasource(datasource, dynamicdatasourceproperties); return datasource; } }
7.2 druid 配置调整
druid 配置类变更:
// 升级前 import com.alibaba.druid.support.http.statviewservlet; import com.alibaba.druid.support.http.webstatfilter; @bean public servletregistrationbean statviewservlet(){ servletregistrationbean bean = new servletregistrationbean(new statviewservlet(), "/druid/*"); // ... } // 升级后 import com.alibaba.druid.support.jakarta.statviewservlet; import com.alibaba.druid.support.jakarta.webstatfilter; import jakarta.servlet.filter; import jakarta.servlet.servlet; @bean public servletregistrationbean statviewservlet(){ servletregistrationbean bean = new servletregistrationbean(new statviewservlet(), "/druid/*"); // ... }
7.3 循环依赖配置
应用配置调整:
# 解决循环依赖问题 spring: main: allow-circular-references: true
7.4 参数名发现器变更
localvariabletableparameternamediscoverer 被废弃:
// 升级前 import org.springframework.core.localvariabletableparameternamediscoverer; // 升级后 import org.springframework.core.standardreflectionparameternamediscoverer;
第八步:异常处理调整
8.1 移除不必要的异常声明
// 升级前 public static connection getconn(dblinkentity dblinkentity) throws dataexception { try{ return new prepsqldto().withconn(dblinkentity).switchconn().getconnection(); }catch (sqlexception d){ throw new dataexception("数据库连接失败"); } } // 升级后 public static connection getconn(dblinkentity dblinkentity) { try{ return new prepsqldto().withconn(dblinkentity).switchconn().getconnection(); }catch (sqlexception d){ throw new runtimeexception("数据库连接失败", d); } }
第九步:测试和验证
9.1 编译测试
# 清理并编译 mvn clean compile # 运行测试 mvn test # 打包 mvn package -dskiptests
9.2 功能测试
- 数据库连接测试
- api 接口测试
- 认证授权测试
- 文件上传下载测试
9.3 性能测试
- 启动时间对比
- 内存使用情况
- 响应时间对比
第十步:常见问题解决
10.1 lombok 编译问题
问题: unable to make field private com.sun.tools.javac.processing.javacprocessingenvironment$discoveredprocessors com.sun.tools.javac.processing.javacprocessingenvironment.discoveredprocs accessible: module jdk.compiler does not "opens com.sun.tools.javac.processing" to unnamed module
解决方案:
- 升级 lombok 到 1.18.30
- 升级 maven-compiler-plugin 到 3.11.0
- 添加编译器参数
<plugin> <groupid>org.apache.maven.plugins</groupid> <artifactid>maven-compiler-plugin</artifactid> <version>3.11.0</version> <configuration> <source>17</source> <target>17</target> <release>17</release> <compilerargs> <arg>--add-opens</arg> <arg>jdk.compiler/com.sun.tools.javac.processing=all-unnamed</arg> <arg>--add-opens</arg> <arg>jdk.compiler/com.sun.tools.javac.util=all-unnamed</arg> </compilerargs> </configuration> </plugin>
10.2 包名冲突问题
问题: 编译时出现 javax.*
和 jakarta.*
包冲突
解决方案:
<dependency> <groupid>conflicting-library</groupid> <artifactid>conflicting-artifact</artifactid> <version>1.0.0</version> <exclusions> <exclusion> <groupid>javax.servlet</groupid> <artifactid>javax.servlet-api</artifactid> </exclusion> </exclusions> </dependency>
10.3 配置类加载失败
问题: 配置类无法正确加载
解决方案:
- 检查包名是否正确
- 确保使用
jakarta.*
包 - 检查依赖版本兼容性
10.4 数据库连接问题
问题: 数据库连接失败
解决方案:
- 检查驱动版本兼容性
- 更新连接配置
- 验证数据库服务状态
10.5 maven 打包问题
问题: maven 打包时出现模块访问权限错误
解决方案: 添加 vm 参数
mvn clean package -dmaven.compiler.fork=true -dmaven.compiler.compilerargs="--add-opens=jdk.compiler/com.sun.tools.javac.processing=all-unnamed --add-opens=jdk.compiler/com.sun.tools.javac.util=all-unnamed"
升级检查清单
升级前检查
- 创建代码备份分支
- 记录当前系统状态
- 准备测试环境
- 确认 java 17 环境
- 备份数据库配置
升级过程检查
- 更新 spring boot 版本
- 更新 java 版本配置
- 迁移包名 (javax → jakarta)
- 更新数据库相关依赖
- 迁移 api 文档框架
- 更新安全认证框架
- 升级工具库版本
- 调整配置文件
- 修复编译错误
- 运行单元测试
- 升级 lombok 和编译器插件
- 处理 base64 编码解码变更
- 更新 xpath 包名
- 替换废弃的类和方法
- 配置循环依赖允许
- 更新 jwt 解析方式
升级后验证
- 编译通过
- 单元测试通过
- 集成测试通过
- 功能测试通过
- 性能测试通过
- 文档更新
- 部署验证
总结
通过本项目的实际升级经验,spring boot 2 到 3 的升级主要涉及以下几个方面:
- 环境升级: java 17 + maven 3.11.0
- 包名迁移: javax → jakarta
- 依赖升级: 多个核心依赖需要升级到兼容版本
- api 变更: 部分 api 接口发生变化
- 配置调整: 配置文件需要相应调整
- 工具库变更: base64、xpath 等工具类的使用方式发生变化
- 框架重构: 授权中心、jwt 解析等需要重构
升级过程中需要特别注意:
- 逐步进行,避免一次性修改过多内容
- 充分测试每个模块的变更
- 保持良好的版本控制和回滚机制
- 及时更新相关文档
- 注意依赖版本查询:https://mvnrepository.com/
到此这篇关于spring boot2升级到3的文章就介绍到这了,更多相关spring boot2升级到3内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论