最近接手了一个从JDK8+SpringBoot2.x升级到JDK17+SpringBoot3.x的项目,整个过程踩了不少坑,也积累了一些经验。Java生态这几年变化很大,JDK17是LTS版本,SpringBoot3.x也带来了很多新特性,这次升级不仅能获得性能提升,还能使用新语法特性。不过升级过程中确实遇到了不少兼容性问题,特别是包路径变更和依赖冲突。
注意:建议在开发环境先完整测试后再上生产,某些改动会影响线上稳定性。
首先修改pom.xml中的Java版本配置:
xml复制<properties>
<java.version>17</java.version>
<!-- 明确指定编译版本 -->
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
这个改动本身不会引起问题,但需要注意:
将父POM升级到Spring Boot 3.5.0:
xml复制<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.5.0</version>
</parent>
同时需要更新相关依赖版本:
xml复制<properties>
<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>
Spring Boot 3不再支持Springfox Swagger,需要迁移到SpringDoc:
xml复制<!-- 替换Swagger为SpringDoc(OpenAPI 3) -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.6.0</version>
</dependency>
注解对应关系:
| 旧注解(Swagger) | 新注解(SpringDoc) |
|---|---|
| @Api | @Tag |
| @ApiOperation | @Operation |
| @ApiModel | @Schema |
| @ApiModelProperty | @Schema |
MySQL驱动坐标和版本变化:
xml复制<!-- 新版MySQL驱动 -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>8.3.0</version>
<scope>runtime</scope>
</dependency>
<!-- Druid适配Spring Boot 3的starter -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-3-starter</artifactId>
<version>${druid.version}</version>
</dependency>
POI 5.x后结构变化较大:
xml复制<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>
变化点:
xml复制<!-- MyBatis-Plus适配Spring Boot 3 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
<!-- Knife4j适配版 -->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
<version>4.4.0</version>
</dependency>
最大的变化是javax.包全部迁移到jakarta.:
java复制// 旧导入
import javax.servlet.http.HttpServletRequest;
import javax.persistence.Entity;
// 新导入
import jakarta.servlet.http.HttpServletRequest;
import jakarta.persistence.Entity;
IDE可以批量替换,但需要注意:
Spring Boot 3推荐使用JDK原生集合类替代Guava:
java复制// 旧代码
ImmutableList.of("a", "b");
Sets.newHashSet(list);
// 新代码
List.of("a", "b");
new HashSet<>(list);
RedisTemplate的泛型检查更严格:
java复制// 旧配置
RedisTemplate<Object, Object> redisTemplate;
// 新配置
RedisTemplate<String, Object> redisTemplate;
对应的操作方法也需要调整:
java复制// 旧代码
redisTemplate.delete(keys); // keys是Set类型
// 新代码
redisTemplate.delete(new ArrayList<>(keys)); // 转为List
WebSecurityConfigurerAdapter已被移除,改为组件式配置:
java复制@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/api/public/**").permitAll()
.anyRequest().authenticated()
)
.formLogin(form -> form
.loginPage("/login")
.permitAll()
);
return http.build();
}
路径匹配规则也有变化:
java复制// 旧模式
antMatchers("/**/*.js")
// 新模式
requestMatchers("/**.js")
报错:No SLF4J providers were found
解决方案:
报错:Invalid value type for attribute 'factoryBeanObjectType'
解决方法:
mybatis-plus-spring-boot3-starterMySQL5InnoDBDialect已移除,现在会根据URL自动选择方言。
配置示例:
yaml复制spring:
jpa:
hibernate:
ddl-auto: none
show-sql: true
FastJSON 2.x需要显式开启AutoType:
java复制// 序列化
JSON.toJSONString(obj, JSONWriter.Feature.WriteClassName);
// 反序列化
JSON.parseObject(json, clazz, JSONReader.Feature.SupportAutoType);
@JsonProperty不再fallback到字段名解决方案:
java复制@Bean
public Jackson2ObjectMapperBuilderCustomizer jacksonCustomizer() {
return builder -> {
builder.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
builder.featuresToEnable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
};
}
Spring Boot 3中RedisCacheManager默认不允许动态创建缓存:
java复制@Bean
public CacheManager cacheManager(RedisConnectionFactory factory) {
return RedisCacheManager.builder(factory)
.cacheDefaults(RedisCacheConfiguration.defaultCacheConfig())
.transactionAware()
.build();
}
为确保升级成功,建议按以下步骤验证:
java -version确认是17mvn clean compile无报错mvn dependency:tree分析依赖冲突升级过程中最耗时的部分是处理各种依赖冲突和行为变化。建议建立一个checklist记录所有修改点,方便后续验证和回滚。Spring Boot 3.x整体上更规范,但一些"宽松"的处理方式被收紧后,会暴露出原有代码中的潜在问题。