jdk8升级JDK21(Springboot2.7.18升级Springboot3.4.0)

目录

背景:

一、maven升级

二、代码改造

2.1 javax替换为jakarta

2.2 swagger2升级swagger3相关更新

2.2.1 新增SpringDocConfig配置类

2.2.2 全局代码更新

2.2.3 全局代码替换(普通+正则替换)

2.3 Mybatis Plus升级

2.4 logback.xml更新

2.5 application.yml更新

三、其他注意事项

3.1 Jdk相关

3.1.1 启动参数

3.2 Spring相关

3.2.1 尾部斜杠匹配取消

3.2.2 RequestParam等传参报错

3.3.3 循环依赖启动报错


背景:

由于各种漏洞原因需要升级Spring6,同时项目上还在使用Jdk8,索性将JDK升级为21,同时springboot也升级为最新发布的Springboot3.4.0,在此记录。

一、maven升级

其中关键依赖升级:

  • Springboot 3.4.0(2024/11/22发布的稳定版,内部依赖spring 6.2.0、tomcat 10.1.33、logback 1.5.12...)
  • Mybatis-plus 3.5.9(Mybatis3.5.16)
  • Shiro 2.0.2
  • Lombok 1.18.36(注意最低兼容版本 jdk17 >= 1.18.22,jdk21 >= 1.18.30)
  • swagger3(springdoc 2.6.0,注意swagger2升级swagger3不再使用io.springfox,需要使用org.springdoc包)
  • mysql-connector-j 8.4.0

部分升级注意事项也写在了注释里

<!-- 2024/11/22发布的稳定版,内部依赖spring 6.2.0、tomcat 10.1.33、logback 1.5.12... -->
<dependency><!-- Import dependency management from Spring Boot --><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>3.4.0</version>
</dependency><dependency><groupId>jakarta.servlet</groupId><artifactId>jakarta.servlet-api</artifactId><scope>compile</scope>
</dependency><!-- Mybatis Plus全家桶升级,参考https://baomidou.com/getting-started/install/ -->
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-bom</artifactId><version>3.5.9</version>
</dependency>
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-bom</artifactId><version>${mybatis-plus-bom.version}</version>
</dependency>
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-generator</artifactId><version>3.5.9</version><exclusions><exclusion><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId></exclusion></exclusions>
</dependency>
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-spring-boot3-starter</artifactId>
</dependency>
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-jsqlparser</artifactId>
</dependency>
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-generator</artifactId>
</dependency><!-- 8.0.30之后的版本,mysql依赖的坐标变更 
可参考https://blogs.oracle.com/mysql/post/mysql-connectorj-has-new-maven-coordinates-->
<dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><version>8.0.31</version>
</dependency><!-- lombok最低兼容版本 jdk17 >= 1.18.22,jdk21 >= 1.18.30 -->
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.36</version>
</dependency><!-- swagger2升级swagger3不再使用io.springfox,需要使用springdoc-->
<dependency><groupId>org.springdoc</groupId><artifactId>springdoc-openapi-starter-webmvc-ui</artifactId><version>2.6.0</version>
</dependency>
<dependency><groupId>org.springdoc</groupId><artifactId>springdoc-openapi-starter-webmvc-api</artifactId><version>2.6.0</version>
</dependency>

其他中间件升级(适配SpringBoot3.4.0版本)


<!-- RocketMQ springboot版,文档地址:https://github.com/apache/rocketmq-spring-->
<dependency><groupId>org.apache.rocketmq</groupId><artifactId>rocketmq-spring-boot-starter</artifactId><version>2.3.1</version>
</dependency><!-- Redisson 文档地址:https://redisson.org/docs/integration-with-spring/#spring-boot-starter-->
<dependency><groupId>org.redisson</groupId><artifactId>redisson-spring-boot-starter</artifactId><version>3.38.1</version>
</dependency><!-- Kafka 此版本springboot默认依赖3.3.0版本spring-kafka-->
<dependency><groupId>org.springframework.kafka</groupId><artifactId>spring-kafka</artifactId>
</dependency><!-- ElasticSearch 此版本springboot支持目前最新版es(8.11.1)-->
<dependency><groupId>co.elastic.clients</groupId><artifactId>elasticsearch-java</artifactId><version>8.11.1</version>
</dependency><!-- Mapstruct 此版本springboot支持目前最新版es(8.11.1)使用时需注意:升级到最新版本后,若想转换List<Entity>,则@Mapper修饰的convert转换类中必须带有Entity单独转换方法,
否则无法直接转换List<Entity>会报错(list转换时会使用单独转换的方法遍历转换)。-->
<dependency><groupId>org.mapstruct</groupId><artifactId>mapstruct</artifactId><version>1.6.3</version>
</dependency><!-- Freemarker-->
<dependency><groupId>org.freemarker</groupId><artifactId>freemarker</artifactId><version>2.3.33</version>
</dependency>

二、代码改造

2.1 javax替换为jakarta

在springboot3中,最低支持的Jdk版本提升到Java 17,移除对Java EE APIs的支持并转向Jakarta EE,因此引入包中import需全局替换。

详细的Springboot3更新可参考官方release note。

Spring-Boot-3.0-Release-Notes

具体需要替换的包:

javax.persistence.* -> jakarta.persistence.*

javax.validation.* -> jakarta.validation.*

javax.servlet.* -> jakarta.servlet.*

javax.annotation.* -> jakarta.annotation.*

javax.transaction.* -> jakarta.transaction.*

2.2 swagger2升级swagger3相关更新

2.2.1 新增SpringDocConfig配置类

/*** spring doc配置*/
@Configuration
public class SpringDocConfig {@Value("${framework.swagger.title}")private String swaggerTitle;@Value("${framework.swagger.description}")private String swaggerDescription;@Value("${framework.swagger.contact.name}")private String swaggerContactName;@Value("${framework.swagger.contact.url}")private String swaggerContactUrl;@Value("${framework.swagger.contact.email}")private String swaggerContactEmail;@Value("${framework.swagger.version}")private String swaggerVersion;@Beanpublic OpenAPI apiInfo() {return new OpenAPI().info(new Info().title(swaggerTitle).description(swaggerDescription).version(swaggerVersion).contact(new Contact().name(swaggerContactName).email(swaggerContactEmail).url(swaggerContactUrl)));}}

2.2.2 全局代码更新

下面是swagger2和swagger3中注解的对照关系,方便升级时对照。

swagger2swagger3说明
@Api@Tag用在请求的类上,表示对类的说明
@ApiIgnore@Hidden隐藏显示
@ApiImplicitParam@Parameter用在请求方法上,指定具体某一个请求参数的详细信息
@ApiImplicitParams@Parameters用在请求方法上,表示一组参数的说明
@ApiModel@Schema用于请求或者响应类上,说明请求或者响应数据
@ApiModelProperty@Schema

用在属性上,描述响应类的属性用,swagger2中的hidden = true属性

相当于swagger3中 的accessMode = READ_ONLY属性

@ApiOperation@Operation

用在请求的方法上,说明方法的用途、作用,对应注解中swagger2中

的value和notes属性对应swagger3中的summary和description属性

@ApiParam@Parameter描述参数信息

2.2.3 全局代码替换(普通+正则替换)

import io.swagger.annotations.Api;
import io.swagger.v3.oas.annotations.tags.Tag;@Api\(value = (.*), tags = (.*)\)
@Tag\( name= $2, description = $1\)@Api\(tags = \{(.*)\}\)
@Tag\(name = $1\)import io.swagger.annotations.ApiOperation;
import io.swagger.v3.oas.annotations.Operation;@ApiOperation\(value = (.*), notes = (.*)\)
@Operation\(summary = $1, description = $2\)@ApiOperation\(value=(.*)\)
@Operation\(summary = $1\)import io.swagger.annotations.ApiResponses;
import io.swagger.v3.oas.annotations.responses.ApiResponses;import io.swagger.annotations.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponse;@ApiResponse\(code = HttpStatus.SC_OK, message = (.*)\)
@ApiResponse(responseCode = "200", description = $1)import io.swagger.annotations.ApiParam;
import io.swagger.v3.oas.annotations.Parameter;#unicode中文范围 \u4e00-\u9eff
@ApiParam\(value = ("[\w|\u4e00-\u9eff]+")
@Parameter\(description = $1import io.swagger.annotations.ApiModelProperty;
import io.swagger.v3.oas.annotations.media.Schema;@ApiModelProperty\((.*)\)
@Schema\(description = $1\)import io.swagger.annotations.ApiModel;
import io.swagger.v3.oas.annotations.media.Schema;

2.3 Mybatis Plus升级

BaseMapper.selectCount()和.count()等方法返回值类型由原来的Integer变为Long,代码需做兼容,例如使用Math.toIntExact()方法将long转为int

例如:

2.4 logback.xml更新

使用 SizeAndTimeBasedRollingPolicy替换TimeBasedRollingPolicy:   

        该策略同时支持按时间和文件大小滚动日志。与旧的 TimeBasedRollingPolicy 类相比,它是更推荐的滚动策略。

文件命名模式调整:

        在 fileNamePattern 中,使用 %d{yyyy-MM-dd}-%i.log 作为文件名格式,这允许日志按照日期命名,并在同一天滚动日志时通过 %i 生成分片文件(如 2024-10-01-1.log, 2024-10-01-2.log 等)。

例如:

<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/${APPDIR}/error/log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern><timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><maxFileSize>20MB</maxFileSize></timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy><!--更改为↓↓↓--><rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"><!-- 归档的日志文件的路径,例如今天是2018-06-13日志,当前写的日志文件路径为file节点指定,可以将此文件与file指定文件路径设置为不同路径,从而将当前日志文件或归档日志文件置不同的目录。而2018-06-13的日志文件在由fileNamePattern指定。%d{yyyy-MM-dd}指定日期格式,%i指定索引 -->
<fileNamePattern>${LOG_PATH}/${APPDIR}/error/log-error-%d{yyyy-MM-dd}-%i.log</fileNamePattern><!-- 除按日志记录之外,还配置了日志文件不能超过20M,若超过20M,日志文件会以索引0开始,命名日志文件,例如log-error-2018-06-13.0.log --><!-- 日志文件的最大大小 --><maxFileSize>10MB</maxFileSize><!-- 最大保留30天的日志 --><maxHistory>30</maxHistory><!-- 总日志文件大小不超过3GB 达到该限制时,将删除最早的日志文件--><totalSizeCap>3GB</totalSizeCap>
</rollingPolicy>

2.5 application.yml更新

① spring.http.encoding.XXX 更新为 server.servlet.encoding.XXX

② spring.redis.XXX 更新为 spring.data.redis.XXX

注意引用的地方也同样替换

三、其他注意事项

3.1 Jdk相关

3.1.1 启动参数

Java9之后模块化特性要求类库声明可被调用的范围若启动报错可在启动项添加对应参数,下面是一些例子。

--add-opens java.base/java.util=ALL-UNNAMED

--add-opens java.base/java.time=ALL-UNNAMED

--add-opens java.base/java.lang=ALL-UNNAMED

--add-opens java.base/java.lang.reflect=ALL-UNNAMED

--add-opens java.base/java.io=ALL-UNNAMED

--add-opens java.base/java.nio=ALL-UNNAMED

--add-opens java.base/sun.nio.ch=ALL-UNNAMED

比如下面这个报错,则启动参数增加 --add-opens java.base/java.nio=ALL-UNNAMED

添加方式:

Idea中:

Linux启动脚本中:

3.2 Spring相关

具体升级变化可参考官方Release-Notes

SpringBoot 2.x->3的变化:

Spring Boot 3.0 Release Notes · spring-projects/spring-boot Wiki · GitHub

Spring升级到6.0的变化:
Spring-Framework-6.0-Release-Notes

3.2.1 尾部斜杠匹配取消

从 Spring Framework 6.0 开始,尾部斜杠匹配配置选项已为 deprecated,其默认值设置为 false。

简单来说,就是比如以前@GetMapping("/list")这样的控制器,可以通过 /list 和 /list/ 两个路径都能访问到,现在只能通过 /list 访问。

3.2.2 RequestParam等传参报错

错误信息:

Name for argument of type [java.lang.String] not specified, and parameter name information not available via reflection. Ensure that the compiler uses the '-parameters' flag.

代码中的使用方式可能为这样:

public String getVersion(@RequestParam String authCode) {}

错误原因:

这个异常java.lang.IllegalArgumentException指出的问题是,在Spring框架中,某个方法参数的名称没有被明确指定,并且无法通过反射获取到。这通常发生在使用注解(如@RequestParam、@PathVariable等)来注入方法参数时,而该参数的名称在编译后的字节码中丢失了。

解决方式:

①规范使用注解,加入value属性,明确指定参数名称

public String getVersion(@RequestParam(value = "authCode", defaultValue = "") String authCode) {}

或者

②若改动太多,可增加maven打包参数:在pom.xml中的maven-compiler-plugin配置里添加<compilerArgument>-parameters</compilerArgument>

<plugins><!-- compiler插件, 设定JDK版本 --><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.8.0</version><configuration><compilerArgs><arg>-parameters</arg></compilerArgs><source>21</source><target>21</target><showWarnings>true</showWarnings></configuration></plugin>
</plugins>

3.3.3 循环依赖启动报错

升级后启动可能报循环依赖问题。

Description:

The dependencies of some of the beans in the application context form a cycle:

   operatePermissionAop defined in file [C:\work\project\XXXX.class]
┌─────┐
|  sysUserOrgServiceImpl
↑     ↓
|  sysAreaInfoServiceImpl
└─────┘
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.

可在yml中增加允许循环依赖配置解决

spring:main:allow-circular-references: true

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/66530.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AI赋能跨境电商:魔珐科技3D数字人破解出海痛点

跨境出海进入狂飙时代&#xff0c;AI应用正在深度渗透并重塑着跨境电商产业链的每一个环节&#xff0c;迎来了发展的高光时刻。生成式AI时代的大幕拉开&#xff0c;AI工具快速迭代&#xff0c;为跨境电商行业的突破与飞跃带来了无限可能性。 由于跨境电商业务自身特性鲜明&…

【HarmonyOS NEXT】鸿蒙应用实现屏幕录制详解和源码

【HarmonyOS NEXT】鸿蒙应用实现屏幕录制详解和源码 一、前言 官方文档关于屏幕录制的API和示例介绍获取简单和突兀。使用起来会让上手程度变高。所以特意开篇文章&#xff0c;讲解屏幕录制的使用。官方文档参见&#xff1a;使用AVScreenCaptureRecorder录屏写文件(ArkTS) 二…

Android - NDK:编译可执行程序在android设备上运行

在android开发中&#xff0c;调试时会把C代码直接编译成可执行程序&#xff0c;运行在android设备上以确认其功能是否正常。 1、基于NDK编译可执行文件 2、push到 /data/local/tmp目录下 3、设置权限&#xff0c;执行。 ndk工程中build.gradle设置 groovy plugins {id com.a…

用matlab调用realterm一次性发送16进制数

realterm采用PutString接口进行发送&#xff0c;需要注意的是发送的16进制数前面要加入0x标志。只有这样&#xff0c;realterm才能将输入的字符串识别为16进制数的形式。 另外,PutString函数支持两个参数输入&#xff0c;第一个参数为字符串&#xff0c;第二个参数为发送形式&…

Python3刷算法来呀,贪心系列题单

1.7号题单 1、​​​​​​k次取反后最大值 2、柠檬水找零 3、分发糖果 示例 1&#xff1a; 输入&#xff1a;ratings [1,0,2] 输出&#xff1a;5 解释&#xff1a;你可以分别给第一个、第二个、第三个孩子分发 2、1、2 颗糖果。示例 2&#xff1a; 输入&#xff1a;ratings…

el-table拖拽表格

1、拖拽插件安装 npm i -S vuedraggable // vuedraggable依赖Sortable.js&#xff0c;我们可以直接引入Sortable使用Sortable的特性。 // vuedraggable是Sortable的一种加强&#xff0c;实现组件化的思想&#xff0c;可以结合Vue&#xff0c;使用起来更方便。 2、引入拖拽函数…

Unity学习笔记(七)使用状态机重构角色攻击

前言 本文为Udemy课程The Ultimate Guide to Creating an RPG Game in Unity学习笔记 攻击状态重构 首先我们重构攻击状态的动画 之前的动画&#xff0c;我们是使用状态(isAttacking)攻击次数(comboCounter)完成动画的过渡&#xff0c;这样虽然能完成功能&#xff0c;但是如…

Windows10环境下安装RabbitMq折腾记

最近有个老项目需要迁移到windows10环境&#xff0c;用的是比较老的rabbitmq安装包&#xff0c;如下所示。经过一番折腾&#xff0c;死活服务起不来&#xff0c;最终果断放弃老版本启用新版本。现在把折腾过程记录下&#xff1a; 一、安装erlang 安装完成后的目录结构&#xff…

了解RabbitMQ中的Exchange:深入解析与实践应用

在分布式系统设计中&#xff0c;消息队列&#xff08;Message Queue&#xff09;扮演着至关重要的角色&#xff0c;而RabbitMQ作为开源消息代理软件的佼佼者&#xff0c;以其高性能、高可用性和丰富的功能特性&#xff0c;成为了众多开发者的首选。在RabbitMQ的核心组件中&…

分布式主键ID生成方式-snowflake雪花算法

这里写自定义目录标题 一、业务场景二、技术选型1、UUID方案2、Leaf方案-美团&#xff08;基于数据库自增id&#xff09;3、Snowflake雪花算法方案 总结 一、业务场景 大量的业务数据需要保存到数据库中&#xff0c;原来的单库单表的方式扛不住大数据量、高并发&#xff0c;需…

Linux 系统搭建网络传输环境汇总

Ubuntu 系统搭建 TFTP 服务器 1. 创建 /home/username/workspace/tftp 目录并赋予最大权限&#xff0c;username 是自己用户名 sudo mkdir -p /home/username/workspace/tftp sudo chmod 777 /home/username/workspace/tftp 2. 安装 tftp-hpa&#xff08; 客户端软件包&#x…

“AI智慧语言训练系统:让语言学习变得更简单有趣

大家好&#xff0c;我是你们的老朋友&#xff0c;一个热衷于探讨科技与教育结合的产品经理。今天&#xff0c;我想和大家聊聊一个让语言学习变得不再头疼的话题——AI智慧语言训练系统。这个系统可是我们语言学习者的福音&#xff0c;让我们一起来揭开它的神秘面纱吧&#xff0…

线性代数考研笔记

行列式 背景 分子行列式&#xff1a;求哪个未知数&#xff0c;就把b1&#xff0c;b2放在对应的位置 分母行列式&#xff1a;系数对应写即可 全排列与逆序数 1 3 2&#xff1a;逆序数为1 奇排列 1 2 3&#xff1a;逆序数为0 偶排列 将 1 3 2 只需将3 2交换1次就可以还原原…

精选2款.NET开源的博客系统

前言 博客系统是一个便于用户创建、管理和分享博客内容的在线平台&#xff0c;今天大姚给大家分享2款.NET开源的博客系统。 StarBlog StarBlog是一个支持Markdown导入的开源博客系统&#xff0c;后端基于最新的.Net6和Asp.Net Core框架&#xff0c;遵循RESTFul接口规范&…

关于FPGA中添加FIR IP核(采用了GOWIN EDA)

文章目录 前言一、IP核二、MATLAB文件三、导出系数COE文件1.设计滤波器2.用官方的matlab代码或者直接用文本文件 四、进行模块化设计源文件 前言 FIR滤波器的特点是其输出信号是输入信号的加权和&#xff0c;权值由滤波器的系数决定。每个系数代表了滤波器在特定延迟位置上的“…

51单片机——中断(重点)

学习51单片机的重点及难点主要有中断、定时器、串口等内容&#xff0c;这部分内容一定要认真掌握&#xff0c;这部分没有学好就不能说学会了51单片机 1、中断系统 1.1 概念 中断是为使单片机具有对外部或内部随机发生的事件实时处理而设置的&#xff0c;中断功能的存在&#…

VVenC 编码器源码结构与接口函数介绍

VVenC VVenC&#xff08;Fraunhofer Versatile Video Encoder&#xff09;是由德国弗劳恩霍夫海因里希研究所&#xff08;Fraunhofer Heinrich Hertz Institute, HHI&#xff09;开发的一个开源的高效视频编码器。它实现了最新的视频编码标准——Versatile Video Coding (VVC)…

耗时一天,我用AI开发了AI小程序

小码哥从事前后端开发近十年&#xff0c;但是随着技术的更新迭代&#xff0c;有时候没有时间和精力去优化UI、实现一些前后端功能&#xff0c;以及解决一些bug。特别是我想开发小码哥AI的移动端&#xff0c;但觉得自己没有那么多时间去研究移动端了&#xff0c;准备放弃了&…

C#中的关键字out和ref的区别

目录 一、out 二、ref 三、拓展 一、out 在 C# 中&#xff0c;out 是一个关键字&#xff0c;通常用于方法参数&#xff0c;表示该参数是输出参数。使用 out 关键字的参数要求在方法内部必须被赋值&#xff0c;而这个参数的值会在方法返回时传递给调用者。可以理解为&#xf…

SpringBootWeb案例-1(day10)

准备工作 需求 & 环境搭建 需求说明 环境搭建 步骤&#xff1a; 准备数据库表(dept、emp)创建 springboot 工程&#xff0c;引入对应的起步依赖&#xff08;web、mybatis、mysql 驱动、lombok&#xff09;配置文件 application.properties 中引入 mybatis 的配置信息&…