Spring Boot 3无缝迁移到Spring Boot 4实战完整代码对比(轻松升级!)

 更新时间:2026年07月06日 10:21:47   作者:有来技术  
作为Java生态中最主流的微服务开发框架,Spring Boot的每一次大版本迭代都牵动着开发者的神经,这篇文章主要介绍了Spring Boot3无缝迁移到Spring Boot4的相关资料,需要的朋友可以参考下

一次真实的项目升级经历,带你避开所有坑,保持业务代码零改动!

前言:为什么要升级到 Spring Boot 4?

Spring Boot 4 带来了性能优化、新特性支持以及长期的技术支持周期。最近我在维护开源项目 youlai-boot 时,完成了从 Spring Boot 3.5.6 到 Spring Boot 4.0.1 的升级。整个过程看似简单,实则暗藏玄机,特别是接口文档(Base64问题)和依赖兼容性这两个大坑。

今天就把这次升级的完整过程、问题排查和解决方案分享给大家,让你在升级路上少走弯路!

一、升级效果预览

先来看看升级前后的对比,让你有个直观感受:

升级前(Spring Boot 3.5.6):

  • 接口文档正常访问:http://localhost:8000/doc.html
  • API 返回标准 JSON 格式
  • 各项功能正常运行

升级后(Spring Boot 4.0.1):

  • ✅ 所有接口保持兼容
  • ✅ 数据库零改动
  • ✅ 业务代码零修改
  • ✅ 接口文档正常可用

二、环境准备与升级原则

2.1 升级前检查清单

在开始升级之前,请务必完成以下检查:

# 1. 确保当前项目在 Spring Boot 3 下正常运行
mvn -DskipTests package

# 2. 启动应用,验证核心功能
java -jar target/your-app.jar --spring.profiles.active=dev

# 3. 验证关键接口
# - 登录接口
# - 用户信息接口
# - 菜单路由接口
# - 接口文档页面

2.2 创建独立分支

# 创建专门的升级分支
git checkout -b chore/upgrade-springboot4

# 记录当前版本信息(非常重要!)
cat pom.xml | grep -A2 -B2 "spring-boot-starter-parent"

三、核心依赖升级清单(pom.xml 改动)

这是升级中最关键的一步,依赖版本选错直接导致项目无法启动!

3.1 Spring Boot Parent 升级

<!-- 升级前 -->
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.5.6</version>
</parent>

<!-- 升级后 -->
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>4.0.1</version>
</parent>

3.2 MyBatis-Plus 必须更换 Starter

<!-- 升级前 -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-spring-boot3-starter</artifactId>
    <version>3.5.5</version>
</dependency>

<!-- 升级后:注意 starter 名称变化! -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-spring-boot4-starter</artifactId>
    <version>3.5.15</version>  <!-- 版本也需要同步升级 -->
</dependency>

3.3 Redisson 版本升级

<!-- 升级前 -->
<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson-spring-boot-starter</artifactId>
    <version>3.51.0</version>
</dependency>

<!-- 升级后 -->
<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson-spring-boot-starter</artifactId>
    <version>4.1.0</version>
</dependency>

3.4 AOP Starter 变化

<!-- 升级前 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

<!-- 升级后(如果你的项目使用AOP) -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aspectj</artifactId>
</dependency>

3.5 完整依赖对比表

依赖项Spring Boot 3.5.6Spring Boot 4.0.1是否必须修改
Spring Boot Parent3.5.64.0.1
MyBatis-Plus3.5.5 + boot3-starter3.5.15 + boot4-starter
Redisson3.51.04.1.0
AOP Starterspring-boot-starter-aopspring-boot-starter-aspectj⚠️按需
Spring AI1.1.22.0.0-M1⚠️如使用
MySQL Driver8.0.338.0.33❌可保持不变
Knife4j/SpringDoc2.8.92.8.9❌可保持不变

四、代码适配:两个关键改动点

4.1 新增 Jackson 全局配置(解决日期序列化问题)

创建一个 JacksonConfig 类,统一处理 JSON 序列化:

import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import tools.jackson.databind.JsonMapper;
import tools.jackson.databind.module.SimpleModule;

import java.math.BigInteger;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.TimeZone;

@Configuration
public class JacksonConfig {

    @Bean
    public JsonMapper jsonMapper() {
        return JsonMapper.builder()
                // 设置日期格式
                .defaultDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"))
                // 设置时区(中国标准时间)
                .defaultTimeZone(TimeZone.getTimeZone("GMT+8"))
                // 处理 Long 类型精度丢失问题
                .addModule(new SimpleModule()
                        .addSerializer(Long.class, ToStringSerializer.instance)
                        .addSerializer(Long.TYPE, ToStringSerializer.instance)
                        .addSerializer(BigInteger.class, ToStringSerializer.instance))
                // LocalDateTime 序列化
                .addModule(new SimpleModule()
                        .addSerializer(LocalDateTime.class,
                            new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))))
                .build();
    }
}

4.2 移除 WebMvcConfigurer 中的 converters 配置

重要提示:这是解决接口文档 Base64 问题的关键!

// ❌ 错误的做法(在 Spring Boot 4 中会导致问题)
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        // 不要在这里移除或替换 converters!
        // 这会破坏 ByteArrayHttpMessageConverter
    }
}

// ✅ 正确的做法:删除这个配置类
// 或者只保留不涉及 converters 的配置
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    // 只配置拦截器、跨域等,不碰 converters
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        // 跨域配置
    }
}

4.3 CacheProperties 包名迁移(RedisCacheConfig 警告)

升级到 Spring Boot 4 后,CacheProperties 的包名发生变化。如果 RedisCacheConfig 仍使用旧包,会触发警告或编译失败。youlai-boot 已同步使用新包,升级时请务必确认:

// Spring Boot 3
import org.springframework.boot.autoconfigure.cache.CacheProperties;

// Spring Boot 4
import org.springframework.boot.cache.autoconfigure.CacheProperties;

4.4 ContentCachingRequestWrapper 构造器变化(验证码过滤器编译报错)

升级到 Spring Boot 4(Spring Framework 7)后,ContentCachingRequestWrapper 的单参构造器被移除,旧代码会直接编译失败:

Expected 2 arguments but found 1

对齐 youlai-boot 的写法即可:

// Spring Boot 3
ContentCachingRequestWrapper requestWrapper = new ContentCachingRequestWrapper(request);

// Spring Boot 4
ContentCachingRequestWrapper requestWrapper = new ContentCachingRequestWrapper(request, -1);

-1 表示不限制缓存大小,适用于登录请求体很小的场景。

4.5 AbstractAuthenticationToken 构造器歧义(短信登录 Token 编译报错)

短信登录的 SmsAuthenticationToken 在 Spring Security 新版本下,如果 super(null) 会触发构造器匹配错误:

constructor AbstractAuthenticationToken in class AbstractAuthenticationToken cannot be applied to given types

原因是构造器只接受 Collection<? extends GrantedAuthority>,需要显式指定泛型类型:

// Spring Boot 3(旧写法)
super(null);
// Spring Boot 4(新写法)
super((Collection<? extends GrantedAuthority>) null);

五、踩坑实录:接口文档返回 Base64 问题

5.1 问题现象

升级后,访问接口文档页面时,发现 /v3/api-docs/** 接口返回的不是 JSON,而是 Base64 编码的字符串:

# 问题现象
curl http://localhost:8000/v3/api-docs/default

# 返回结果(异常):
"eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"

# 正常应该返回:
{
  "openapi": "3.0.1",
  "info": {
    "title": "API文档",
    "version": "v1.0"
  },
  // ... 其他JSON内容
}

5.2 问题根源

经过排查,发现问题出在:

  1. Spring Boot 4 中,Spring Framework 7 已经标记了一些 WebMvcConfigurer 方法为 @Deprecated(forRemoval = true)
  2. 如果手动配置 configureMessageConverters,可能会移除掉关键的 ByteArrayHttpMessageConverter
  3. 缺少这个 Converter,byte[] 类型的数据会被 Jackson 序列化为 Base64 字符串

5.3 解决方案

按照第四节的建议:

  1. 移除所有对 configureMessageConverters 的自定义配置
  2. 使用全局 JsonMapper 来统一 JSON 处理策略
  3. 信任 Spring Boot 的自动配置

六、配置文件检查清单

升级后,检查以下配置文件是否正常:

6.1 application.yml 基础配置

server:
  port: 8000
  servlet:
    context-path: /

spring:
  application:
    name: youlai-boot
  profiles:
    active: @profiles.active@  # 确保这个配置正确

  # 数据库配置(保持不变)
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/youlai?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
    username: root
    password: 123456

6.2 接口文档配置

springdoc:
  api-docs:
    path: /v3/api-docs # 确认路径正确
    enabled: true
  swagger-ui:
    path: /swagger-ui.html # Swagger UI路径
    enabled: true
  group-configs:
    - group: "default"
      paths-to-match: "/api/**"
      packages-to-scan: com.youlai.**.controller

6.3 安全白名单配置

确保以下路径在安全白名单中:

security:
  unsecured-urls:
    - /doc.html # Knife4j文档页
    - /v3/api-docs/** # OpenAPI JSON
    - /swagger-ui/** # Swagger UI
    - /webjars/** # 静态资源
    - /favicon.ico
    # ... 其他业务白名单

七、完整回归测试清单

升级完成后,请按照以下清单逐一验证:

编译与启动测试

  • mvn clean package -DskipTests 编译成功
  • java -jar target/app.jar 启动成功
  • 控制台无异常错误日志

接口文档测试

  • 访问 http://localhost:8000/doc.html 能打开文档页面
  • 访问 http://localhost:8000/v3/api-docs/default 返回标准 JSON
  • 文档中的接口能正常展开/折叠

核心业务测试

  • 登录接口:POST /api/v1/auth/login
  • 获取用户信息:GET /api/v1/users/me
  • 获取菜单路由:GET /api/v1/menus/routes
  • 数据库 CRUD 操作正常

基础设施测试

  • Redis 连接正常(查看缓存是否生效)
  • 数据库事务正常
  • 文件上传下载正常(如涉及)

八、升级经验总结

8.1 三条黄金原则

  1. 最小改动原则:只改必须改的,能不动业务代码就不动
  2. 信任框架原则:相信 Spring Boot 的自动配置,不要过度自定义
  3. 逐步验证原则:每改一个依赖,就验证一次核心功能

8.2 常见问题速查表

问题现象可能原因解决方案
启动报错:ClassNotFoundException依赖版本不兼容检查 starter 是否使用 boot4 版本
接口文档返回 Base64ByteArrayHttpMessageConverter 缺失移除自定义 converters 配置
JSON 日期格式不对Jackson 配置问题使用全局 JsonMapper 配置
数据库连接失败驱动版本问题保持 MySQL 驱动版本不变

8.3 推荐的升级步骤

1. 备份当前项目 ✅
2. 创建升级分支 ✅
3. 升级 parent 版本 ✅
4. 逐个升级关键依赖 ✅
5. 适配代码(JacksonConfig)✅
6. 移除有问题配置 ✅
7. 编译测试 ✅
8. 启动验证 ✅
9. 功能回归测试 ✅
10. 合并到主分支 ✅

九、结语

Spring Boot 3 到 4 的升级,表面上只是版本号的改变,实际上是一次框架底座的全面刷新。通过本文的实践指南,你可以:

  1. 安全完成升级:避开 Base64 等常见大坑
  2. 保持业务稳定:接口协议、数据库结构零改动
  3. 快速定位问题:掌握问题排查方法和工具

如果你在升级过程中遇到其他问题,欢迎在评论区留言讨论。也可以参考完整的示例项目:youlai-boot,查看实际的升级代码对比。

到此这篇关于Spring Boot3无缝迁移到Spring Boot4实战完整代码对比的文章就介绍到这了,更多相关Spring Boot3无缝迁移Spring Boot4内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Spring ApplicationListener源码解析

    Spring ApplicationListener源码解析

    这篇文章主要为大家介绍了Spring ApplicationListener源码解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-01-01
  • Spring Security学习笔记(一)

    Spring Security学习笔记(一)

    这篇文章主要介绍了Spring Security的相关资料,帮助大家开始学习Spring Security框架,感兴趣的朋友可以了解下
    2020-09-09
  • SpringBoot的HTTPS配置实现

    SpringBoot的HTTPS配置实现

    本文主要介绍了SpringBoot的HTTPS配置实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-04-04
  • Spring InitializingBean的使用方式

    Spring InitializingBean的使用方式

    InitializingBean是Spring框架中的一个生命周期接口,用于在Bean的属性设置完成后执行自定义的初始化逻辑,本文给大家介绍spring InitializingBean的使用方式,感兴趣的朋友小编一起看看吧
    2026-01-01
  • Mybatis框架中Interceptor接口的使用说明

    Mybatis框架中Interceptor接口的使用说明

    这篇文章主要介绍了Mybatis框架中Interceptor接口的使用说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09
  • IDEA部署Tomcat的超详细图文教程

    IDEA部署Tomcat的超详细图文教程

    最近迫于无奈从我哪破旧的Eclipse转换到了IDEA,然后就是超多的不习惯,下面这篇文章主要给大家介绍了关于IDEA部署Tomcat的相关资料,文中通过图文介绍的非常详细,需要的朋友可以参考下
    2023-02-02
  • java操作Redis缓存设置过期时间的方法

    java操作Redis缓存设置过期时间的方法

    这篇文章主要介绍了java操作Redis缓存设置过期时间的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-06-06
  • Java四种元注解介绍

    Java四种元注解介绍

    元注解是用来修饰注解的注解,在java.lang.annotation包下,当我们需要自己定义一个注解去做某些事情的时候,我们要对该注解进行一些限制,确保我们注解的作用域,这篇文章主要介绍了Java四种元注解介绍,需要的朋友可以参考下
    2024-08-08
  • mybatis返回的map结果如何设置有序

    mybatis返回的map结果如何设置有序

    这篇文章主要介绍了mybatis返回的map结果如何设置有序,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-01-01
  • 一篇文章带你了解Java 中序列化与反序列化

    一篇文章带你了解Java 中序列化与反序列化

    这篇文章主要介绍了Java 序列化与反序列化(Serialization),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-07-07

最新评论