您的位置 首页 java

关于升级 Spring 等依赖的一些经验

到公司后,熟悉了一些项目后,发现大部分项目的依赖都比较陈旧,比如某些项目还在使用 Spring 3.x 的版本。所以,在进行需求开发时,也顺手把一些项目的依赖给升级了一下。周五,一个小伙伴问我关于升级 Spring 的经验。正好趁此机会,把一些经验总结一下。

下面的描述以 Java 8 为准,没有在其他版本 Java 上试验过。参考时,请慎重。描述的原则如下:

  1. 尽量选择还在维护中的版本,而不是已经 End of Life 的过时版。这样有问题可以及时反馈并得到修复。
  2. Java 8 是目标版本,所以,一定要兼容 Java 8。

Spring Framework 升级

Spring Framework 从 3.2.6.RELEASE 开始提供 BOM。可以利用 BOM 简化 Spring 依赖声明:

 <!-- D瓜哥 ·  -->
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-framework-bom</artifactId>
            <version>5.3.22</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>  

这样,就不需要重复声明 Spring 依赖的版本,直接使用即可。 Spring Framework Bom 保证了 Spring 自身依赖的版本统一。

这里,关于 Spring 的升级,还有几点需要说明:

  1. 从 Spring 3.0.0.RELEASE 到 Spring 3.1.4.RELEASE,Spring 有一个 spring- ASM ,如果不再使用这个区间的 Spring,请把这个依赖删掉。
  2. 如果使用了 Apache Velocity 1.X 作为前端模板,由于 Spring 5+ 将相关集成代码删除,所以,只能将 Spring 升级到 4.3.30.RELEASE。相关 BOM 如下:
  3. <!– D瓜哥 · –> < dependencyManagement > < dependencies > < dependency > < groupId >org.springframework</ groupId > < artifactId >spring-framework-bom</ artifactId > < version >4.3.30.RELEASE</ version > < type >pom</ type > < scope >import</ scope > </ dependency > </ dependencies > </ dependencyManagement >
  4. 建议把 Spring XML 配置文件中,指明 schema Location spring-*. XSD 的版本号删除掉,这样升级 Spring 时,会自动使用对应版本的 XSD 约束。

另外,Spring 全家桶还提供了很多其他的 BOM,这里列出一部分供参考使用:

 <!-- D瓜哥 ·  -->
<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-bom</artifactId>
    <version>2021.2.2</version>
    <type>pom</type>
    <scope>import</scope>
</dependency>
<dependency>
    <groupId>org.springframework.integration</groupId>
    <artifactId>spring-integration-bom</artifactId>
    <version>5.5.14</version>
    <type>pom</type>
    <scope>import</scope>
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-bom</artifactId>
    <version>5.7.3</version>
    <type>pom</type>
    <scope>import</scope>
</dependency>
<dependency>
    <groupId>org.springframework.session</groupId>
    <artifactId>spring-session-bom</artifactId>
    <version>2021.2.0</version>
    <type>pom</type>
    <scope>import</scope>
</dependency>  

这里只是列出来它们的最新版本,并没有测试它们的兼容性。

Spring 4+ 与 iBATIS

Spring 4+ 删除了内置的 iBATIS 支持。可以通过添加下面这两个依赖来将使用 iBATIS 的应用升级到 Spring 4+。

 <!-- D瓜哥 ·  -->
<dependency>
    <groupId>org. MyBATIS </groupId>
    <artifactId>mybatis-2-spring</artifactId>
    <version>1.1.0</version>
</dependency>
<dependency>
    <groupId>org.apache.ibatis</groupId>
    <artifactId>ibatis-sqlmap</artifactId>
    <version>2.3.4.726</version>
</dependency>  
  • 首先,iBATIS 与 mybatis 的代码包名不一样,无须担心存在冲突问题。
  • 其次, mybatis-2-spring 就是将 Spring 删除的那部分代码重新打包了一下,和 MyBATIS 集成原理完全不同,也无须担心存在冲突问题。
  • 最后, org.springframework:spring-orm 这个依赖是为了集成实现 JPA 标准的 ORM 框架准备的。所以,无论使用 MyBATIS,还是使用 iBATIS,都不需要这个依赖。

Spring Boot

没有搞过 Spring Boot 1.X 到 2.X 的升级过程,所以,没有经验可以分享。

在 Spring Boot 2.X 中升级时,只需要修改 spring-boot-starter-parent 的版本即可。部分配置项可能需要调整。具体情况,就需要查看升级说明了: Spring Boot Release Notes 。

有一点需要注意:从 Spring Boot 2.6.0 开始,默认开启了循环检查并且禁用了循环依赖。如果有循环依赖,升级到 Spring Boot 2.6+ 时,可能会报错。建议修改程序;不想修改程序的,可以通过设置 spring.main.allow-circular-references=true 来运行循环依赖。

MySQL 依赖升级

如果跟随 Spring Boot 的脚步,MySQL 依赖选择 8+ 版。将MySQL 依赖的版本从 5.x 升级到 8.x 时,一定要检查数据库连接 字符串 是否包含时区配置。如果没有,请添加 serverTimezone=Asia/Shanghai 的配置项。上线后,建议检查一下新增数据的日期字符数据是否正确。

具体原因请看: 关于 MySQL 新版连接驱动时区对齐问题的研究 。

Quartz

Quartz 的依赖坐标从 1.X 升级到 2.X 时发生了变化,需要做出调整。最新的依赖坐标如下:

 <!-- D瓜哥 ·  -->
<dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz</artifactId>
    <version>2.3.2</version>
</dependency>
<dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz-jobs</artifactId>
    <version>2.3.2</version>
</dependency>  

将 Quartz 升级到 2.X 版本,还需要修改关于 Quartz 的相关配置:

  1. 由于 org.springframework.scheduling.quartz.CronTriggerBean 不支持 Quartz 2.X,则需要将其替换为 org.springframework.scheduling.quartz.CronTriggerFactoryBean
  2. 更新依赖引用的方式,由 local= 更新为 bean= ,具体代码如下:
  3. <!– D瓜哥 · –> < bean id= “autoplanScheduler” class= “org.springframework.scheduling.quartz.SchedulerFactoryBean” > < property name= “triggers” > < list > <!– 将依赖应用由 local= 更新为 bean= –> < ref bean= “myCronTrigger” /> </ list > </ property > < property name= “autoStartup” value= “true” /> </ bean >

Validation API & Hibernate Validation

由于 Oracle 把 JavaEE 甩给了 Eclipse 基金会,但是却没有授权 Eclipse 基金会使用 javax 包名。所以,Eclipse 基金会投票决定将 JavaEE 改名为 JakartaEE,同时后续推出的新标准全部使用标准以 jakarta. 为包前缀,同时,一大批的相关依赖的坐标都发生了变化。其中,就包括 Validation API,由 javax.validation:validation-api 改为 jakarta.validation:jakarta.validation-api ,从 2.0.1 开始,就发生了变化。但是,2.X 版本的依赖只是把 Maven 坐标发生了变化,从 3.0.0 开始,包前缀开始发生变化。目前主流还是 javax.validation:validation-api

 <!-- D瓜哥 ·  -->
<dependency>
    <groupId>jakarta.validation</groupId>
    <artifactId>jakarta.validation-api</artifactId>
    <version>2.0.1</version>
</dependency>
<!--或-->
<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>2.0.1.Final</version>
</dependency>  

其实,这两个包没啥区别,只是“换了个马甲”。

Validation API 最主流的实现,Hibernate Validator 的坐标也有调整,根据 Migration Guide – Hibernate Validator 显示,从 6.0.0 开始,将 groupId org.hibernate 改为 org.hibernate.validator 。值得一提的是, Hibernate Validator 为了方便迁移,还是使用旧的 groupId 跟踪发布了同等实现及同等版本的依赖。最新的 6.X 的依赖如下:

 <!-- D瓜哥 ·  -->
<dependency>
    <groupId>org.hibernate.validator</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>6.2.4.Final</version>
</dependency>  

由几点需要注意:

  1. 这个版本的 Hibernate Validator 依赖了 jakarta.validation:jakarta.validation-api:2.0.2
  2. 由于 groupId 发生了变化,Maven 不能解决这类的“依赖冲突”,所以需要手动检查并排除低版本 Hibernate Validator;
  3. D瓜哥遇到了一次线上问题,低版本的 Hibernate Validator 和高版本的 Hibernate Validator 起了冲突。所以,还请务必排除低版本的 Hibernate Validator 实现。

ProtoBuf

有些应用还依赖了 ProtoBuf,在 Status of protobuf-java 2.x / 3.x compatibility 中讨论了 Protocol 2.x 与 3.x 的兼容性问题。可以考虑升级到 3.x,我升级过程中,没有遇到过啥问题。最新的依赖如下:

 <!-- D瓜哥 ·  -->
<dependency>
    <groupId>com.google.protobuf</groupId>
    <artifactId>protobuf-java</artifactId>
    <version>3.21.5</version>
</dependency>  

Bouncy Castle

Bouncy Castle Java Cryptography APIs 是 Java Cryptography APIs 的主流发布版。在发布 1.71 版时,他们发布了针对 JDK 1.8+ 的版本,同时将 -jdk18on 作为这系列 API 的 artifactId 后缀。详细介绍请看: Bouncy Castle LATEST JAVA RELEASES 。完整依赖列表如下:

 <!-- D瓜哥 ·  -->
<!-- *-jdk1[1/2/3/4/5/6] 和 *-jdk15on 都用如下依赖升级 -->
< bouncycastle .version>1.71</bouncycastle.version>

<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcprov-jdk18on</artifactId>
    <version>${bouncycastle.version}</version>
</dependency>
<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcprov-ext-jdk18on</artifactId>
    <version>${bouncycastle.version}</version>
</dependency>
<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcutil-jdk18on</artifactId>
    <version>${bouncycastle.version}</version>
</dependency>
<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcpkix-jdk18on</artifactId>
    <version>${bouncycastle.version}</version>
</dependency>
<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcmail-jdk18on</artifactId>
    <version>${bouncycastle.version}</version>
</dependency>
<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcjmail-jdk18on</artifactId>
    <version>${bouncycastle.version}</version>
</dependency>
<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcpg-jdk18on</artifactId>
    <version>${bouncycastle.version}</version>
</dependency>
<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bctls-jdk18on</artifactId>
    <version>${bouncycastle.version}</version>
</dependency>  

如果升级到这个版本,需要手动增加依赖。升级成本略大,还请斟酌处理。

日志

关于日志相关升级,请看日志最佳实践探究。

ASM

根据 ASM Versions 显示,从 ASM 5.0 开始,完整支持 Java 8。所以,ASM 的版本也要升级到 5+。最新版依赖如下:

 <!-- D瓜哥 ·  -->
<asm.version>9.3</asm.version>

<dependency>
    <groupId>org.ow2.asm</groupId>
    <artifactId>asm</artifactId>
    <version>${asm.version}</version>
</dependency>
<dependency>
    <groupId>org.ow2.asm</groupId>
    <artifactId>asm-commons</artifactId>
    <version>${asm.version}</version>
</dependency>
<dependency>
    <groupId>org.ow2.asm</groupId>
    <artifactId>asm-util</artifactId>
    <version>${asm.version}</version>
</dependency>
<dependency>
    <groupId>org.ow2.asm</groupId>
    <artifactId>asm-tree</artifactId>
    <version>${asm.version}</version>
</dependency>
<dependency>
    <groupId>org.ow2.asm</groupId>
    <artifactId>asm-analysis</artifactId>
    <version>${asm.version}</version>
</dependency>
<dependency>
    <groupId>org.ow2.asm</groupId>
    <artifactId>asm-test</artifactId>
    <version>${asm.version}</version>
    <scope>test</scope>
</dependency>  

CGLib

根据 Release cglib 3.2.0 · cglib/cglib 显示,从 CGLib 3.2.0 开始,可以更好地支持 Java 8 了。所以,建议把 CGLib 也升级到 3.2.0+ 的版本。最新版本的依赖如下:

 <!-- D瓜哥 ·  -->
<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>3.3.0</version>
</dependency>  

关于 CGLib 对 Java 8 支持的讨论请看: Support Java 8 · Issue #8 · cglib/cglib 。

Javassist

Javassist 从 3.12.1.GA 升级到 3.13.0-GA 时,将 groupId javassist 改为 org.javassist 。另外,它从 3.24.0-GA 开始,编译版本改为 1.8 (测试编译版本为 11 )。考虑到兼容性以及后续升级方便,最少需要升级到 3.24.0-GA。这里选择了当前最新版 3.29.1-GA。所以,在升级该 Jar 包时,需要注意修改 Maven 坐标声明中的 groupId 。最新坐标如下:

 <!-- D瓜哥 ·  -->
<dependency>
    <groupId>org.javassist</groupId>
    <artifactId>javassist</artifactId>
    <version>3.29.1-GA</version>
</dependency>  

有几点需要特别注意:

  1. 由于 groupId 发生了变化,Maven 不能解决这类的“依赖冲突”,所以需要手动检查并排除低版本 Javassist;
  2. 如果同时依赖了两个版本的 Javassist,就要看加载顺序了。如果先加载了低版本的 Javassist,那么就可能会出现运行时异常,提示不能识别高版本的字节码。

RESTEasy

原来使用 RESTEasy 来标注 REST 接口,切换到 RPC 框架后,RESTEasy 的实现类就毫无用处了。可以直接排除掉:

 <!-- D瓜哥 ·  -->
<exclusions>
    <exclusion>
        <groupId>org.jboss.resteasy</groupId>
        <artifactId>*</artifactId>
    </exclusion>
</exclusions>  

需要注意的是,原来的 RESTEasy 的注解,还保留在代码中,所以,还需要加一个注解的依赖:

 <!-- D瓜哥 ·  -->
<dependency>
    <groupId>org.jboss.resteasy</groupId>
    <artifactId>jaxrs-api</artifactId>
    <version>3.0.12.Final</version>
</dependency>  

如果项目中没有相关注解,也不依赖使用 RESTEasy 注解的外部接口,则这个依赖也不需要了。

文章来源:智云一二三科技

文章标题:关于升级 Spring 等依赖的一些经验

文章地址:https://www.zhihuclub.com/177181.shtml

关于作者: 智云科技

热门文章

网站地图