JDK版本升级
整理pom.xml文件
将pom.xml文件中所有的版本号归纳到一起,方便后续升级时对所有的版本挨个处理。
下载安装jdk21
在官网中下载jdk21版本并安装
使用mvn命令查询升级包
使用命令:mvn versions:display-dependency-updates
。该命令显示项目中所有依赖项的最新可用版本。执行此命令后,Maven 会扫描 pom.xml
文件,并列出当前依赖项的版本以及可用的最新版本。 输出如下:
Windows PowerShell
版权所有(C) Microsoft Corporation。保留所有权利。
安装最新的 PowerShell,了解新功能和改进!https://aka.ms/PSWindows
PS D:\workspace\project\1-CRM\CRM-master> mvn versions:display-dependency-updates
[INFO] Scanning for projects...
[INFO]
[INFO] ---------------------------< com.test:CRM >---------------------------
[INFO] Building CRM 1.19.0.0
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- versions-maven-plugin:2.8.1:display-dependency-updates (default-cli) @ CRM ---
[INFO] The following dependencies in Dependency Management have newer versions:
[INFO] antlr:antlr ........................................ 2.7.7 -> 20030911
[INFO] ch.qos.logback:logback-access ......................... 1.2.6 -> 1.5.8
[INFO] ch.qos.logback:logback-classic ........................ 1.2.6 -> 1.5.8
[INFO] ch.qos.logback:logback-core ........................... 1.2.6 -> 1.5.8
[INFO] com.atomikos:transactions-jdbc ........................ 4.0.6 -> 6.0.0
[INFO] com.atomikos:transactions-jms ......................... 4.0.6 -> 6.0.0
[INFO] com.atomikos:transactions-jta ......................... 4.0.6 -> 6.0.0
[INFO] com.couchbase.client:java-client ...................... 3.1.7 -> 3.7.2
[INFO] com.datastax.oss:java-driver-core ................... 4.11.3 -> 4.17.0
[INFO] com.datastax.oss:java-driver-core-shaded ............ 4.11.3 -> 4.17.0
[INFO] com.datastax.oss:java-driver-mapper-processor ....... 4.11.3 -> 4.17.0
[INFO] com.datastax.oss:java-driver-mapper-runtime ......... 4.11.3 -> 4.17.0
[INFO] com.datastax.oss:java-driver-metrics-micrometer ..... 4.11.3 -> 4.17.0
[INFO] com.datastax.oss:java-driver-metrics-microprofile ... 4.11.3 -> 4.17.0
[INFO] com.datastax.oss:java-driver-query-builder .......... 4.11.3 -> 4.17.0
[INFO] com.datastax.oss:java-driver-test-infra ............. 4.11.3 -> 4.17.0
[INFO] com.datastax.oss:native-protocol ...................... 1.5.0 -> 1.5.1
…………
[INFO] The following dependencies in Dependencies have newer versions:
[INFO] cn.hutool:hutool-all ................................. 5.8.1 -> 5.8.32
[INFO] com.alibaba:druid-spring-boot-starter ............... 1.1.21 -> 1.2.23
[INFO] com.alibaba:easyexcel ................................. 3.3.2 -> 4.0.3
[INFO] com.alibaba:fastjson ................................ 1.2.79 -> 2.0.53
[INFO] com.aliyun:aliyun-java-sdk-core ....................... 4.6.1 -> 4.7.1
[INFO] com.aliyun:dysmsapi20170525 .......................... 2.0.24 -> 3.0.0
[INFO] com.auth0:java-jwt .................................... 3.2.0 -> 4.4.0
[INFO] com.baomidou:mybatis-plus-boot-starter ................ 3.5.2 -> 3.5.8
[INFO] com.baomidou:mybatis-plus-generator ................... 3.5.2 -> 3.5.8
[INFO] com.bestvike:linq ..................................... 3.1.0 -> 6.0.0
[INFO] com.dtflys.forest:forest-spring-boot-starter ........ 1.5.28 -> 1.5.36
[INFO] com.github.oshi:oshi-core ............................. 6.4.0 -> 6.6.4
[INFO] com.github.ulisesbocchio:jasypt-spring-boot-starter ... 3.0.3 -> 3.0.5
[INFO] com.tencentcloudapi:tencentcloud-sdk-java .......... 3.1.934 -> 4.0.11
[INFO] com.thoughtworks.xstream:xstream ..................... 1.4.4 -> 1.4.20
[INFO] com.twelvemonkeys.imageio:imageio-jpeg ............... 3.8.2 -> 3.11.0
[INFO] com.twelvemonkeys.imageio:imageio-pnm ................ 3.8.2 -> 3.11.0
[INFO] dom4j:dom4j ................................. 1.6.1 -> 20040902.021138
[INFO] io.github.lognet:grpc-spring-boot-starter ............. 3.4.1 -> 5.1.5
[INFO] net.coobird:thumbnailator ............................ 0.4.8 -> 0.4.20
[INFO] org.apache.ftpserver:ftpserver-core ................... 1.1.1 -> 1.2.0
[INFO] org.apache.shiro:shiro-spring ......................... 1.6.0 -> 2.0.1
[INFO] org.apache.tika:tika-core ........................ 1.27 -> 3.0.0-BETA2
[INFO] org.apache.xmlgraphics:batik-transcoder ................. 1.14 -> 1.17
[INFO] org.springframework.integration:spring-integration-mqtt ...
[INFO] 5.5.7 -> 6.3.4
[INFO] org.xerial:sqlite-jdbc ............................ 3.28.0 -> 3.46.1.0
[INFO]
[INFO] The following dependencies in pluginManagement of plugins have newer versions:
[INFO] org.springframework.boot:spring-boot-maven-plugin ..... 2.5.5 -> 3.3.3
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.240 s
[INFO] Finished at: 2024-09-19T10:10:47+08:00
[INFO] ------------------------------------------------------------------------
PS D:\workspace\project\1-CRM\CRM-master>
使用EMT4J插件
EMT4J
介绍
EMT4J(Eclipse Migration Toolkit for Java)是一个致力于简化Java版本迁移过程的开源项目。它专注于处理三个长期支持(LTS)版本:Java 8、11、17和21之间的迁移。EMT4J提供了多种工具集,包括Maven插件,Java代理及命令行接口,用于分析项目代码与目标Java版本间的不兼容性。分析结果支持TXT、JSON和HTML格式输出,帮助开发团队识别并解决升级过程中的兼容问题。
配置EMT4J
在pom.xml
文件中添加插件配置
<plugin>
<groupId>org.eclipse.emt4j</groupId>
<artifactId>emt4j-maven-plugin</artifactId>
<version>0.8.0</version>
<!-- 可以将检查过程绑定到 Maven 构建周期的某个阶段,但不建议。 -->
<!-- <executions>-->
<!-- <execution>-->
<!-- <phase>process-test-classes</phase>-->
<!-- <goals>-->
<!-- <goal>check</goal>-->
<!-- </goals>-->
<!-- </execution>-->
<!-- </executions>-->
<configuration>
<!-- 当前版本 -->
<fromVersion>8</fromVersion>
<!-- 期望升级版本 -->
<toVersion>21</toVersion>
<outputFile>report.html</outputFile>
</configuration>
</plugin>
使用
执行命令:
mvn emt4j:check
命令执行成功后,在项目根路径下会生成一个文件report.html
,使用浏览器打开可看到所有扫描到的问题,根据实际情况可对应的进行修改。
OpenRewrite插件
配置
<plugin>
<groupId>org.openrewrite.maven</groupId>
<artifactId>rewrite-maven-plugin</artifactId>
<version>5.30.0</version>
<configuration>
<activeRecipes>
<!-- 升级到 Java 21 -->
<!-- https://docs.openrewrite.org/recipes/java/migrate/upgradetojava21 -->
<recipe>org.openrewrite.java.migrate.UpgradeToJava21</recipe>
</activeRecipes>
</configuration>
<dependencies>
<dependency>
<groupId>org.openrewrite.recipe</groupId>
<artifactId>rewrite-migrate-java</artifactId>
<version>2.13.0</version>
</dependency>
</dependencies>
</plugin>
使用
命令:
mvn rewrite:run
配置属性兼容
介绍
SpringBoot3提供了一个spring-boot-properties-migrator模块
,帮助更新application.properties
或application.yml
配置文件。一旦作为依赖关系添加到你的项目中,它不仅会在启动时分析你的应用程序的环境并打印诊断结果,而且还会在运行时为你临时迁移属性。
配置
在pom.xml中添加下面的依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-properties-migrator</artifactId>
<scope>runtime</scope>
</dependency>
**注意:**使用完成后,需要将该依赖移除。
mybatis-plus版本升级
要使用新的依赖
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>${mybatis.plus.version}</version>
</dependency>
旧的依赖会导致启动报错:
2024-09-24 19:21:49.997 ERROR ConsoleInfoBuffer -
org.springframework.beans.factory.BeanDefinitionStoreException: Invalid bean definition with name 'powerMapper' defined in file [D:\workspace\project\1-CRM\CRM-master\target\classes\com\test\mapper\auth\PowerMapper.class]: Invalid value type for attribute 'factoryBeanObjectType': java.lang.String
at com.test.CRMApplication.main(CRMApplication.java:51)
2024-09-24 19:25:35.507 ERROR SpringApplication - Application run failed
org.springframework.beans.factory.BeanDefinitionStoreException: Invalid bean definition with name 'powerMapper' defined in file [D:\workspace\project\1-CRM\CRM-master\target\classes\com\test\mapper\auth\PowerMapper.class]: Invalid value type for attribute 'factoryBeanObjectType': java.lang.String
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.getTypeForFactoryBean(AbstractAutowireCapableBeanFactory.java:857) ~[spring-beans-6.1.12.jar:6.1.12]
at org.springframework.beans.factory.support.AbstractBeanFactory.getType(AbstractBeanFactory.java:743) ~[spring-beans-6.1.12.jar:6.1.12]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAnnotationOnBean(DefaultListableBeanFactory.java:735) ~[spring-beans-6.1.12.jar:6.1.12]
at org.springframework.boot.sql.init.dependency.AnnotationDependsOnDatabaseInitializationDetector.detect(AnnotationDependsOnDatabaseInitializationDetector.java:36) ~[spring-boot-3.3.3.jar:3.3.3]
at org.springframework.boot.sql.init.dependency.DatabaseInitializationDependencyConfigurer$DependsOnDatabaseInitializationPostProcessor.detectDependsOnInitializationBeanNames(DatabaseInitializationDependencyConfigurer.java:152) ~[spring-boot-3.3.3.jar:3.3.3]
at org.springframework.boot.sql.init.dependency.DatabaseInitializationDependencyConfigurer$DependsOnDatabaseInitializationPostProcessor.postProcessBeanFactory(DatabaseInitializationDependencyConfigurer.java:115) ~[spring-boot-3.3.3.jar:3.3.3]
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:363) ~[spring-context-6.1.12.jar:6.1.12]
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:197) ~[spring-context-6.1.12.jar:6.1.12]
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:789) ~[spring-context-6.1.12.jar:6.1.12]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:607) ~[spring-context-6.1.12.jar:6.1.12]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.3.3.jar:3.3.3]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754) [spring-boot-3.3.3.jar:3.3.3]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:456) [spring-boot-3.3.3.jar:3.3.3]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:335) [spring-boot-3.3.3.jar:3.3.3]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1363) [spring-boot-3.3.3.jar:3.3.3]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1352) [spring-boot-3.3.3.jar:3.3.3]
at com.test.CRMApplication.main(CRMApplication.java:51) [classes/:?]
动态数据源及配置文件加密
使用dynamic-datasource
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot3-starter</artifactId>
<version>${dynamic.datasource.version}</version>
</dependency>
当第三方服务需要指定的datasource时,可通过如下方式获取
@Configuration
public class LiquibaseConfiguration {
@Resource
private DataSource dataSource;
/**
* 用户模块Liquibase
*/
@Bean(name = "springLiquibase")
public SpringLiquibase springLiquibase() {
DynamicRoutingDataSource ds = (DynamicRoutingDataSource) dataSource;
DataSource db1 = ds.getDataSource(DynamicDSConstant.DB1);
SpringLiquibase liquibase = new SpringLiquibase();
// ……(省略)
liquibase.setDataSource(db1);
// ……(省略)
return liquibase;
}
}
主要步骤:
- 将DataSource引入
- 将DataSource转为DynamicRoutingDataSource,再通过DynamicRoutingDataSource方法getDataSource(“dsName”)方法获取。
Forest框架
需要更新到支持SpringBoot3.x版本的依赖,旧的依赖会导致自动注入失败,主要原因是内部使用的包名变了。
<dependency>
<groupId>com.dtflys.forest</groupId>
<artifactId>forest-spring-boot3-starter</artifactId>
<version>1.5.36</version>
</dependency>
循环依赖问题
启动提示:
Description:
The dependencies of some of the beans in the application context form a cycle:
authorizationAspect
↓
globalVariable
↓
pathFinder
↓
alarmReport
↓
alarmManager
┌─────┐
| threadManager
↑ ↓
| encryptAuthorization
└─────┘
Action:
Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the dependency cycle between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true.
暂时在配置文件中添加配置,允许循环依赖。
spring:
main:
allow-circular-references: true
swagger升级OpenApi3
替换依赖
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-spring-boot-starter</artifactId>
<version>4.5.0</version>
</dependency>
替换注解
替换导包
通过全局替换(Ctrl+Shift+F)将旧依赖引用替换,如:
import io.swagger.annotations.ApiOperation;
替换为 import io.swagger.v3.oas.annotations.Operation;
。
替换注解
使用结构替换可以在确保匹配的情况下最大程度保证替换的准确性
idea中的结构替换:edit-> find -> replace structurally
- @ApiOperation替换为@Operation
替换导包:import io.swagger.annotations.ApiOperation;
替换为 import io.swagger.v3.oas.annotations.Operation;
。
替换注解
@ApiOperation(value = $value$, notes = $notes$)
$MethodType$ $Method$($ParameterType$ $Parameter$);
@Operation(summary = $value$, description = $notes$)
$MethodType$ $Method$($ParameterType$ $Parameter$);
- @Api替换@Tag
替换导包:import io.swagger.annotations.Api;
替换为import io.swagger.v3.oas.annotations.tags.Tag;
替换注解
@Api(tags= $tag$)
class $Class$ {}
@Tag(name = $tag$)
class $Class$ {}
- @ApiModel替换为@Schema
替换导包:import io.swagger.annotations.ApiModel;
和import io.swagger.annotations.ApiModelProperty;
替换为import io.swagger.v3.oas.annotations.media.Schema;
。
替换注解:
@ApiModel(value = $value$)
class $Class$ {}
@Schema(title = $value$)
class $Class$ {}
@ApiModelProperty(value = $value$)
$FieldType$ $Field$ = $Init$;
@Schema(title = $value$)
$FieldType$ $Field$ = $Init$;
其他可能需要替换的注解:
@Api
→@Tag
@ApiIgnore
→@Parameter(hidden = true)
或@Operation(hidden = true)
或@Hidden
@ApiImplicitParam
→@Parameter
@ApiImplicitParams
→@Parameters
@ApiModel
→@Schema
@ApiModelProperty(hidden = true)
→@Schema(accessMode = READ_ONLY)
@ApiModelProperty
→@Schema
@ApiOperation(value = "foo", notes = "bar")
→@Operation(summary = "foo", description = "bar")
@ApiParam
→@Parameter
@ApiResponse(code = 404, message = "foo")
→@ApiResponse(responseCode = "404", description = "foo")
需要注意的是,在上述替换中,都是固定参数个数的,如果参数个数可能不确定时,要变换一下替换模板
如下例,当存在多个入参需要全部替换时。
效果如下:
$ Parameter $ 添加 filter,count => [0, ∞],表示匹配任意数量入参的方法。
Shorten fully qualified names:使用短的全类名
Use static imports:使用静态 import 包