背景
最近把项目中的技术框架做一次升级,最重要的就是SpringBoot从2.7.x升级到3.0.x,当然还会有一些周边的框架也会连带着升级,比如Mybatis Plus,SpringCloud等,话不多说直接看看有哪些事情要做。
具体事项
主要分两类,第一类是单纯的提升版本,主要如下:
1.jdk升级
SpringBoot3需要jdk17以上,看下官网的介绍。
2.构建工具Maven需要升级,3.5+以上。
3.SpringCloud需要升级,原来是2021.0.3,现在决定升级到2022.0.4,中途也尝试过SpringCloud暂时不升级,但是启动失败了,果断决定升级,二者的对照关系请参考https://start.spring.io/actuator/info。
4.Mybatis,Mybatis-plus需要升级,分别升级到3.5.13,3.5.3.2。
第二类是由于版本升级带来的一些配置和代码的变更,主要如下:
1. javax.需要批量替换
import javax.annotation. 替换为import jakarta.annotation.
import javax.servlet.替换为import jakarta.servlet.
这个我也是有点不解,为什么连路径都要做迁移,这个会有一些连带的改变,比如使用的一些第三方jar使用的是javax.servlet/annotation,那我们就需要找到其高版本看是否切换到了jakarta.servlet/annotation,如果不支持那我们的整体升级可能都要叫停,刚开始也想过找到一些老的jar保证编译不报错,但是运行的时候发现根本不行,因为SpringBoot,Spring等在底层使用的时候都切到了jakarta,为了适应新版本框架必须要改,庆幸的是用的第三方jar都有相应的高版本支持。
2.Spring Cloud OpenFeign升级以后,FeignContext不存在
之前有框架代码中获取FeignBean的需求,代码如下:
public static <T> T getFeignBean(String beanName, Class<T> tClass) { FeignContext feignContext = (FeignContext)getBean("feignContext"); return feignContext.getInstance(beanName, tClass); }
需要调整为FeignClientFactory:
public static <T> T getFeignBean(String beanName, Class<T> tClass) { FeignClientFactory feignContext = (FeignClientFactory)getBean("feignContext"); return feignContext.getInstance(beanName, tClass); }
3.redis配置修改
之前是spring.redis.xxx,现在需要修改为spring.data.redis.xxx。
4.mybatis plus由3.2.0升级到3.5.3.2以后带来的几个调整
4.1 id-type: UUID调整为id-type: ASSIGN_UUID
4.2 拦截器路径以及构造方式的变化
之前如下:
@Configuration public class MybatisPlusConfig { /** * 分页插件 */ @Bean public PaginationInterceptor paginationInterceptor() { return new PaginationInterceptor(); }
现在如下:
@Configuration public class MybatisPlusConfig { /** * 分页插件 */ @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); return interceptor; }
4.3 selectCount返回值由Integer变更为Long
这个好改,直接按照idea的提示改成Math.toIntExact(xxxMapper.selectCount)。
带来的好处
先说说我最直观的一个好处,jdk由11升级到17以后空指针的异常提示清晰多了,可以明确的知道是哪个对象空,分别以jdk11和jdk17为例测试一段链式调用的NPE异常,测试代码如下:
static class User{ int age; public int getAge(){ return age; } } @Test public void testNPE(){ List<User> list = new ArrayList(); list.add(null); list.stream().filter(o -> o.getAge() >9).collect(Collectors.toList()) }
分别看下在jdk11和jdk17下的报错提示。
jdk11
java.lang.NullPointerException at NpeTest.lambda$testNPE$0(NpeTest.java:41) at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:176) at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1655) at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484) at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474) at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913) at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578) at NpeTest.testNPE(NpeTest.java:41)
jdk17
java.lang.NullPointerException: Cannot invoke "NpeTest$User.getAge()" because "o" is null at NpeTest.lambda$testNPE$0(NpeTest.java:41) at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:178) at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625) at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509) at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499) at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921) at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:682)
其次就是一次老生常谈的好处,比如性能提升,安全加固等,我了解的还很浅薄,待我慢慢发掘以后再跟大家分享。
推荐阅读
https://spring.io/blog/2022/05/24/preparing-for-spring-boot-3-0
https://docs.spring.io/spring-boot/docs/3.0.10/reference/htmlsingle/#getting-help
https://github.com/spring-projects-experimental/spring-boot-migrator
https://blog.csdn.net/dreamcatcher1314/article/details/131137388
- SpringBoot2 SpringBoot 3.0springboot2 springboot 3.0 springboot2 springboot2 springboot springboot2 springboot swagger3 swagger springboot2 springboot mybatis springboot2 springboot lettuce redis springboot2 springboot spring3 spring springboot2 springboot后台 管理系统 springboot2 springcache springboot springboot2 springboot mybatis3 mybatis