JDK8+SpringBoot2.x 升级 JDK 17 + Spring Boot 3.x

JDK8+SpringBoot2.x 升级 JDK 17 + Spring Boot 3.x 日志

修改pom.xml中的Java版本

复制代码
<properties>
    <java.version>17</java.version>
    <!-- 添加JVM参数,保持兼容性 -->
    <maven.compiler.source>17</maven.compiler.source>
    <maven.compiler.target>17</maven.compiler.target>
</properties>

这一步直接运行没有什么问题

Spring Boot 2.x → 3.x 迁移

修改父pom.xml的核心变更:

复制代码
<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.5.0</version>
</parent>

<properties>
    <!-- 升级相关依赖版本 -->
    <!-- <log4j2.version>2.23.1</log4j2.version>
    <druid.version>1.2.20</druid.version> 跟随Springboot日志-->
    <swagger.version>2.2.0</swagger.version> <!-- SpringDoc替代 -->
    <fastjson.version>2.0.51</fastjson.version>
    <mapstruct.version>1.5.5.Final</mapstruct.version>
    <mybatis-plus.version>3.5.6</mybatis-plus.version>
</properties>

需要修改的依赖项

复制代码
移除或替换不兼容的依赖
<!-- 1. 替换Swagger为SpringDoc(OpenAPI 3) -->
<dependency>
    <groupId>org.springdoc</groupId>
    <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
    <version>2.6.0</version>
</dependency>


<!-- 2. 升级MySQL驱动(必需) -->
<!-- Spring Boot 3 已经不再管理 这个坐标:mysql:mysql-connector-java -->
<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
    <version>8.3.0</version>
    <scope>runtime</scope>
</dependency>

<!-- 3. 升级其他核心依赖 -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-3-starter</artifactId>
    <version>${druid.version}</version>
</dependency>

<!-- 4. 升级POI -->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>5.2.5</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>5.2.5</version>
</dependency>

<!-- 5. 升级knife4j(如果仍需使用) -->
<dependency>
    <groupId>com.github.xiaoymin</groupId>
    <artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
    <version>4.4.0</version>
</dependency>

poi-ooxml-schemas包的问题:
Dependency 'org.apache.poi:poi-ooxml-schemas:5.2.3' not found
POI 5.x 以后结构变了
以前: poi 、poi-ooxml 、poi-ooxml-schemas
现在(5.x 开始):poi-ooxml 默认内置 精简版 schema
如果你确实需要完整版 schema:✔️ 用 poi-ooxml-full或✔️ 用 ooxml-schemas
目前:先把org.apache.poi:poi-ooxml-schemas:5.2.3 注释掉了。【此处需要后期注意下】

更新阿里云Maven仓库

复制代码
阿里云 Maven 旧地址已经 停止维护 + http 被阻断
<repositories>
    <repository>
        <id>aliyun-maven</id>
        <url>https://maven.aliyun.com/repository/public</url>
    </repository>

    <repository>
        <id>central</id>
        <url>https://repo1.maven.org/maven2/</url>
    </repository>
</repositories>

<pluginRepositories>
    <pluginRepository>
        <id>aliyun-maven</id>
        <url>https://maven.aliyun.com/repository/public</url>
    </pluginRepository>
</pluginRepositories>

代码层面的迁移工作

复制代码
1.javax → jakarta 包迁移
# 使用IDE的批量替换或迁移工具
# 修改所有import javax.* 为 import jakarta.*

旧	新
jakarta.persistence	jakarta.persistence
jakarta.servlet	jakarta.servlet
javax.validation	jakarta.validation
javax.ws.rs	jakarta.ws.rs
javax.annotation	jakarta.annotation
javax.xml.bind	jakarta.xml.bind


Security配置更新
JPA实体注解更新
Servlet API相关类的更新

2.注释掉了SwaggerConfig类,不再使用Swagger

3.ImmutableList:Spring Boot 3 + JDK 17 中完全不需要 Guava,直接用 JDK 自带的即可,改用List

Swagger 注解包替换成 SpringDoc 的新版注解

复制代码
import io.swagger.annotations.ApiModelProperty;替换为
import io.swagger.v3.oas.annotations.media.Schema;

@Schema(description = "xxx")
改为 @Schema(description = "xxx")


旧(Springfox)	新(SpringDoc / OpenAPI 3)
@Api	@Tag
@ApiOperation	@Operation
@ApiImplicitParam	@Parameter
@ApiModel	@Schema
@ApiModelProperty	@Schema

RedisUtils代码修改

  1. 老版代码使用了 Guava 的 ImmutableList、Sets.newHashSet()、Lists.newArrayList() 等工具类

升级到 Spring Boot 3 + Java 17 后,没有引入 Guava

Spring Boot 3 已经推荐用 JDK 自带集合类替代 Guava

解决方法:

ImmutableList.of(...) → List.of(...)

Sets.newHashSet(list) → new HashSet<>(list)

Lists.newArrayList() → new ArrayList<>()

建议删除 Guava 依赖,全部用 JDK 集合

  1. RedisTemplate 泛型导致 delete / multiGet 报错
    原因:

升级后,你把 RedisTemplate 泛型改成了 RedisTemplate<String, Object>

老代码里很多地方使用 Set 或 List 作为 key,类型不匹配

Spring Data Redis 的 ValueOperations<K,V>.multiGet(Collection keys) 要求泛型 K 与 RedisTemplate 一致

delete() 接收 String 或 Collection,Set 不匹配

解决方法:

所有 Redis key 统一使用 String 类型

Set → Set

multiGet(List) 直接传 List,不用转 Set

delete(Collection) 传 Set 或 List

  1. ConvertingCursor / scanDel 泛型问题

原因:

老版代码使用 ConvertingCursor 来自动反序列化 cursor

Spring Boot 3 + Spring Data Redis 泛型更加严格

executeWithStickyConnection 要求返回 Cursor<byte[]>,ConvertingCursor<byte[], String> 泛型不兼容

解决方法:

不使用 ConvertingCursor,返回原生 Cursor<byte[]>

循环时手动 deserialize → String key = redisTemplate.getStringSerializer().deserialize(cursor.next())

再调用 delete(key)

修改SpringSecurityConfig

找不到符号: 类 WebSecurityConfigurerAdapter

Spring Boot 3 + Spring Security 6 已经移除了 WebSecurityConfigurerAdapter

原因:Spring Security 推崇 基于组件的配置,用 SecurityFilterChain + PasswordEncoder + UserDetailsService 代替继承方式

SLF4J出问题

运行报错:SLF4J(W): No SLF4J providers were found.

这说明 Spring Boot 启动时找不到 StatusPrinter2 类,这是 Logback 相关类。

Logback 版本不兼容

你项目中 logback-classic:1.2.9 与 Spring Boot 3.5.0(Spring Boot 3 依赖 Spring Framework 6)不兼容。

Spring Boot 3.5.0 使用 Logback 1.4.x,StatusPrinter2 是 Logback 1.4 的新类,而 1.2.9 没有这个类。

SLF4J 冲突

Standard Commons Logging discovery in action with spring-jcl: please remove commons-logging.jar from classpath in order to avoid potential conflicts

SLF4J(W): No SLF4J providers were found.

SLF4J(W): Defaulting to no-operation (NOP) logger implementation

你的 classpath 里既有 commons-logging 又有老版本 SLF4J,导致日志系统混乱。

解决方案:彻底跟随 Spring Boot 3 的日志版本 --->删除 <log4j2.version>2.17.0</log4j2.version>

<logback.version>1.2.9</logback.version>

Mybatis-plus 冲突

报错:Invalid value type for attribute 'factoryBeanObjectType': java.lang.String

升级 Mybatis-Plus 版本为 3.5.5 版本即可,需要注意下 Maven 的坐标标识 是mybatis-plus-spring-boot3-starter,这点和SpringBoot 2 的依赖坐标mybatis-plus-boot-starter有所区别。

mvn package报错:Maven 使用的 JDK 不是 17

ERROR\] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.14.0:compile (default-compile) on project eladmin-common: Fatal error compiling: 无效的目标发行版: 17 解决方案:修改 MAVEN_HOME 下的 jdk 指向?但不能影响其他jdk8的项目 #### Spring Boot 启动时无法找到数据库连接配置 Spring Boot 3.x 不再自动识别 spring.datasource.druid.url,而是要求 标准的 Spring Boot 数据源属性 url、username、password 放在 spring.datasource 下,而不是 spring.datasource.druid.url。 其他 Druid 特有配置仍然可以保留,Spring Boot 3.x 会自动注入到 DruidDataSource。 #### Hibernate Dialect 类名 MySQL5InnoDBDialect 已经找不到了 Spring Boot 3.x 升级到了 Hibernate 6。 Hibernate 6 移除了老的 Dialect 类(如 MySQL5InnoDBDialect、MySQL5Dialect)。 解决方案:修改配置 如果你 不强制指定 Dialect,Spring Boot 3 + Hibernate 6 会根据数据库连接 URL 自动选择 Dialect: spring: jpa: hibernate: ddl-auto: none (这个不能乱开,控制 JPA 启动时是否自动创建/更新/验证表结构) show-sql: true #### spring Data JPA 与 JSQLParser 版本不兼容 Spring Data JPA 3.5.0 里的 JSqlParserQueryEnhancer 调用了 Select.getPlainSelect()。 你引入的 JSQLParser 版本是 4.6。----\>发现是在mybatis-plus-spring-boot3-starter(3.5.5)里引入了jsqlparser的4.6 但在 JSQLParser 4.x 中,Select.getPlainSelect() 方法已经 被移除或改名。 因此运行时报 NoSuchMethodError。 把mybatis-plus-spring-boot3-starter升到 3.5.15 问题解决了 #### RedisTemplate that could not be found 前面RedisUtils里把RedisTemplate\ redisTemplate 改成了 RedisTemplate\ 原本Spring Boot 应该要自动配置 RedisTemplate,但是项目里存在RedisConfig里面定义的 RedisTemplate bean的泛型还是\,将其改成\即可 #### com.aliyun.oss.OSS could not be found 在AlyOssWebConfig中,写了一个Oss的Bean就解决了 #### LimitAspect 里的 RedisTemplate\同步修改为 RedisTemplate\ 原先的Number count = redisTemplate.execute(redisScript, keys,limit.count(), limit.period());这个方法会报错, 这里的keys原先是List类型,修改成List类型即可 因为RedisTemplate\ 的泛型是:RedisTemplate\ execute() 的方法签名是: T execute(RedisScript script, List keys, Object... args) 这里的 List 必须匹配 RedisTemplate 的 Key 类型 #### Spring Security 的 FilterChain 初始化失败 Spring Boot 3 / Spring MVC 6 不再支持 getPatternsCondition(), 而你的 SpringSecurityConfig 里还在用 Boot2 风格的 RequestMappingInfo API(或基于 AntPatterns 的老式 PathMatch)。 把所有: entry.getKey().getPatternsCondition().getPatterns() 替换成: entry.getKey().getPathPatternsCondition().getPatternValues() #### 调接口报错:org.springframework.web.util.pattern.PatternParseException: No more pattern data allowed after {\*...} or \*\* pattern element Spring Boot 3.x规定: 在 ** 或 {*xxx} 这种"捕获全部"通配符之后,不允许再继续写别的路径内容。 问题定位在:SpringSecurityConfig配置类中,安全链配置上原先有类似"/**/*.js"的写法,全都拆成改成/**/*.js改为/**.js #### 调登录接口,AuthorizationController.java 报错: Cannot find cache named 'data' for Builder[public java.util.List me.zhengjie.modules.system.service.impl.DataServiceImpl.getDeptIds(me.zhengjie.modules.system.service.dto.UserDto)] caches=[data] | key=''user:' + #p0.id' | keyGenerator='' | cacheManager='' | cacheResolver='' | condition='' | unless='' | sync='false 原因: RedisCacheManager 在 Boot 2.x 中默认 允许动态创建缓存,找不到某个命名的缓存的时候会自动创建该缓存空间,Boot 3.x中 RedisCacheManager 不再默认允许动态创建,需要手动添加 解决方案: 在redis的配置类RedisConfig中添加: @Bean public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) { // 使用已有的默认配置 RedisCacheConfiguration config = redisCacheConfiguration(); // 构建 RedisCacheManager,允许动态创建缓存 return RedisCacheManager.builder(redisConnectionFactory) .cacheDefaults(config) .transactionAware() .build(); } #### JSONObject 强制转换成 MenuDto 类型不匹配,抛出异常 原因是fastjson从原来的1.2.x升级到现在的2.x,存储进redis里时FastJSON会自动的填充Type类型,FASTJSON支持AutoType功能,这个功能会在序列化的JSON字符串中带上类型信息,在反序列化时,不需要传入类型,实现自动类型识别。 \*\* 必须显式打开才能使用。 \*\* 和fastjson 1.x不一样,fastjson 1.x为了兼容有一个白名单,在fastjson 2中,没有任何白名单,也不包括任何Exception类的白名单,必须显式打开才能使用。这可以保证缺省配置下是安全的。 修改序列化和反序列化的实现代码:注意引入FastJSON2的包 import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONReader; import com.alibaba.fastjson2.JSONWriter; /** * Value 序列化 * fastjson1.x升级到2.0 做调整 * @author / * @param */ class FastJsonRedisSerializer implements RedisSerializer { private final Class clazz; FastJsonRedisSerializer(Class clazz) { super(); this.clazz = clazz; } @Override public byte[] serialize(T t) { if (t == null) { return new byte[0]; } return JSON.toJSONString(t, JSONWriter.Feature.WriteClassName).getBytes(StandardCharsets.UTF_8); } @Override public T deserialize(byte[] bytes) { if (bytes == null || bytes.length <= 0) { return null; } String str = new String(bytes, StandardCharsets.UTF_8); return JSON.parseObject(str, clazz, JSONReader.Feature.SupportAutoType); } #### @JsonProperty使用不当使得Jackson 映射搞"断"了 之前某些地方为了导出中文表头方便,在字段上使用@JsonProperty(中文),例如:("订单ID") private Long orderId; 且新版本变动后:Spring Boot 3 升级 → Jackson + Bean Validation 行为变严格了,把你之前"其实一直就不太合理但还能跑"的设计给暴露出来了。 在 老 Jackson 中: 当字段上有 @JsonProperty("中文名") 但 JSON 里传的是 leaderId 👉 很多情况下 反序列化仍然会 fallback 到字段名本身 所以你虽然写的是: @JsonProperty("订单负责人id") private Long leaderId; 但是 Jackson 还是会把 leaderId 绑定进去 👉 所以不会是 null 👉 校验不会报错 👉 你就以为"没问题" 但 新 Jackson(Boot 3)改了行为 现在规则是: 只认 @JsonProperty 指定的名字 ❌ 不再 fallback 到原字段名 也就是说: @JsonProperty("订单负责人id") = 你明确告诉 Jackson: 👉 JSON 必须写 "订单负责人id" 👉 不能再写 "leaderId" 于是现在: JSON 里是 leaderId 后端只认 订单负责人id → leaderId = null 于是: @NotNull → 直接校验失败 解决方案:使用@JsonPropertyDescription替换 #### Jackson 序列化和反序列化的问题 报错1.:org.springframework.data.redis.serializer.SerializationException: Could not read JSON:Problem deserializing 'setterless' property ("roles"): no way to handle typed deser with setterless yet 报错2.:Caused by: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "label" (class me.zhengjie.modules.system.service.dto.MenuDto), not marked as ignorable (19 known properties: "updateBy", "cache", "iframe", "path", "componentName", "createTime", "hidden", "pid", "permission", "createBy", "updateTime", "title", "icon", "type", "id", "menuSort", "children", "subCount", "component"\]) at \[Source: REDACTED (`StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION` disabled); line: 1, column: 470\] (through reference chain: java.util.ArrayList\[0\]-\>me.zhengjie.modules.system.service.dto.MenuDto\["label"\]) 反序列化时: Jackson 默认是通过 setter 或构造函数来填充对象的属性的。由于 roles 并不是一个直接的字段,而是通过方法动态生成的,所以 Jackson 无法直接把 JSON 中的 roles 映射到 JwtUserDto 对象的某个字段 Jackson 在反序列化 JSON 时遇到了类中没有定义的属性 解决方法:声明roles+@Data注释 添加JacksonConfig配置:反序列化时候遇到不匹配的属性并不抛出异常 #### 时间对象反序列化默认成时间戳 Jackson要显式配置:featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS) ConfigurerAdapter里的@EnableWebMvc要注释掉(@EnableWebMvc 会导致 spring.jackson 等许多 YAML 配置失效) 注释掉原先的HTTP消息转换器配置 #### PerformanceResults 实体类枚举映射问题 枚举类型本来应该是字符串类型,被映射了0,1,2,3 解决方法在字段上面增加@Enumerated(EnumType.STRING)

相关推荐
方璧13 小时前
限流的算法
java·开发语言
元Y亨H13 小时前
Nacos - 服务注册
java·微服务
曲莫终13 小时前
Java VarHandle全面详解:从入门到精通
java·开发语言
天若有情67313 小时前
校园二手交易系统实战开发全记录(vue+SpringBoot+MySQL)
vue.js·spring boot·mysql
一心赚狗粮的宇叔13 小时前
中级软件开发工程师2025年度总结
java·大数据·oracle·c#
while(1){yan}13 小时前
MyBatis Generator
数据库·spring boot·java-ee·mybatis
奋进的芋圆14 小时前
DataSyncManager 详解与 Spring Boot 迁移指南
java·spring boot·后端
计算机程序设计小李同学14 小时前
个人数据管理系统
java·vue.js·spring boot·后端·web安全
小途软件14 小时前
用于机器人电池电量预测的Sarsa强化学习混合集成方法
java·人工智能·pytorch·python·深度学习·语言模型