Spring?Boot2升級到3的詳細步驟記錄
項目升級概覽
基于 公司科創(chuàng)項目 的實際升級經(jīng)驗,本文檔詳細記錄了從 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月
第一步:環(huán)境準備
1.1 Java 環(huán)境升級
檢查當前 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 數(shù)據(jù)庫相關依賴升級
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
類型,現(xiàn)在返回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);
動態(tài)數(shù)據(jù)源升級:
<!-- 升級前 --> <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 版本,可能會出現(xiàn)數(shù)據(jù)源配置讀取失敗的錯誤:
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 版本,可能讀取不到數(shù)據(jù)庫配置。
第三步:包名遷移 (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) { // 根據(jù)新版本API調(diào)整 // 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>
注意: 授權中心需要重構(gòu),使用 Spring Authorization Server 替換原有的 OAuth2 實現(xiàn)。
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;
第七步:配置類調(diào)整
7.1 動態(tài)數(shù)據(jù)源配置調(diào)整
配置類變更:
// 升級前 @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 配置調(diào)整
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 循環(huán)依賴配置
應用配置調(diào)整:
# 解決循環(huán)依賴問題 spring: main: allow-circular-references: true
7.4 參數(shù)名發(fā)現(xiàn)器變更
LocalVariableTableParameterNameDiscoverer 被廢棄:
// 升級前 import org.springframework.core.LocalVariableTableParameterNameDiscoverer; // 升級后 import org.springframework.core.StandardReflectionParameterNameDiscoverer;
第八步:異常處理調(diào)整
8.1 移除不必要的異常聲明
// 升級前 public static Connection getConn(DbLinkEntity dbLinkEntity) throws DataException { try{ return new PrepSqlDTO().withConn(dbLinkEntity).switchConn().getConnection(); }catch (SQLException d){ throw new DataException("數(shù)據(jù)庫連接失敗"); } } // 升級后 public static Connection getConn(DbLinkEntity dbLinkEntity) { try{ return new PrepSqlDTO().withConn(dbLinkEntity).switchConn().getConnection(); }catch (SQLException d){ throw new RuntimeException("數(shù)據(jù)庫連接失敗", d); } }
第九步:測試和驗證
9.1 編譯測試
# 清理并編譯 mvn clean compile # 運行測試 mvn test # 打包 mvn package -DskipTests
9.2 功能測試
- 數(shù)據(jù)庫連接測試
- API 接口測試
- 認證授權測試
- 文件上傳下載測試
9.3 性能測試
- 啟動時間對比
- 內(nèi)存使用情況
- 響應時間對比
第十步:常見問題解決
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
- 添加編譯器參數(shù)
<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 包名沖突問題
問題: 編譯時出現(xiàn) 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 數(shù)據(jù)庫連接問題
問題: 數(shù)據(jù)庫連接失敗
解決方案:
- 檢查驅(qū)動版本兼容性
- 更新連接配置
- 驗證數(shù)據(jù)庫服務狀態(tài)
10.5 Maven 打包問題
問題: Maven 打包時出現(xiàn)模塊訪問權限錯誤
解決方案: 添加 VM 參數(shù)
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"
升級檢查清單
升級前檢查
- 創(chuàng)建代碼備份分支
- 記錄當前系統(tǒng)狀態(tài)
- 準備測試環(huán)境
- 確認 Java 17 環(huán)境
- 備份數(shù)據(jù)庫配置
升級過程檢查
- 更新 Spring Boot 版本
- 更新 Java 版本配置
- 遷移包名 (javax → jakarta)
- 更新數(shù)據(jù)庫相關依賴
- 遷移 API 文檔框架
- 更新安全認證框架
- 升級工具庫版本
- 調(diào)整配置文件
- 修復編譯錯誤
- 運行單元測試
- 升級 Lombok 和編譯器插件
- 處理 Base64 編碼解碼變更
- 更新 XPath 包名
- 替換廢棄的類和方法
- 配置循環(huán)依賴允許
- 更新 JWT 解析方式
升級后驗證
- 編譯通過
- 單元測試通過
- 集成測試通過
- 功能測試通過
- 性能測試通過
- 文檔更新
- 部署驗證
總結(jié)
通過本項目的實際升級經(jīng)驗,Spring Boot 2 到 3 的升級主要涉及以下幾個方面:
- 環(huán)境升級: Java 17 + Maven 3.11.0
- 包名遷移: javax → jakarta
- 依賴升級: 多個核心依賴需要升級到兼容版本
- API 變更: 部分 API 接口發(fā)生變化
- 配置調(diào)整: 配置文件需要相應調(diào)整
- 工具庫變更: Base64、XPath 等工具類的使用方式發(fā)生變化
- 框架重構(gòu): 授權中心、JWT 解析等需要重構(gòu)
升級過程中需要特別注意:
- 逐步進行,避免一次性修改過多內(nèi)容
- 充分測試每個模塊的變更
- 保持良好的版本控制和回滾機制
- 及時更新相關文檔
- 注意依賴版本查詢:https://mvnrepository.com/
到此這篇關于Spring Boot2升級到3的文章就介紹到這了,更多相關Spring Boot2升級到3內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Spring框架接入單機Redis兩種實現(xiàn)方式解析
這篇文章主要介紹了Spring框架接入單機Redis兩種實現(xiàn)方式解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-09-09java使用監(jiān)聽器實現(xiàn)一個統(tǒng)計網(wǎng)站在線人數(shù)的示例
本文主要介紹了java使用監(jiān)聽器實現(xiàn)一個統(tǒng)計網(wǎng)站在線人數(shù)的示例,具有一定的參考價值,有需要的朋友可以了解一下。2016-10-10java 8 lambda表達式list操作分組、過濾、求和、最值、排序、去重代碼詳解
java8的lambda表達式提供了一些方便list操作的方法,主要涵蓋分組、過濾、求和、最值、排序、去重,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧2024-01-01