将若依(RuoYi)框架从适配 Spring Boot 2 的版本升级到 Spring Boot 3

将若依(RuoYi)框架从适配 Spring Boot 2 的版本升级到 Spring Boot 3

你想要将若依(RuoYi)框架从适配 Spring Boot 2 的版本升级到 Spring Boot 3,这是一个涉及依赖、配置、API 兼容等多方面的系统性升级工作。

一、升级前准备

  1. 确认若依版本:优先选择若依官方已适配 Spring Boot 3 的版本(如 RuoYi v4.7.0+ 有适配分支),若使用自定义改造版本,需逐一处理兼容性问题。
  2. 环境要求:Spring Boot 3 要求 JDK 17+(放弃 JDK 8/11 支持),需先升级本地 / 服务器 JDK 到 17 及以上。
  3. 备份代码:升级前完整备份项目代码,避免升级过程中代码丢失。

二、核心升级步骤

1. 升级 Maven/Gradle 依赖

核心是修改 pom.xml(Maven)或 build.gradle(Gradle)中的依赖版本,以下以 Maven 为例:

(1)修改父依赖为 Spring Boot 3
<!-- 原 Spring Boot 2 依赖 --> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.7.12</version> <relativePath/> </parent> <!-- 升级为 Spring Boot 3.x(推荐 3.2.x 稳定版) --> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.2.3</version> <relativePath/> </parent>
(2)升级 Spring Cloud 依赖(若使用微服务版本)

Spring Boot 3 对应 Spring Cloud 2022.x 及以上版本(不再使用 Finchley/Greenwich 等版本号,改为年份命名):

<!-- Spring Cloud 版本管理 --> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>2022.0.4</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
(3)升级若依核心依赖

若依核心依赖需适配 Spring Boot 3,建议使用官方适配版本:

<!-- 若依核心依赖(以单体版为例) --> <dependency> <groupId>com.ruoyi</groupId> <artifactId>ruoyi-common</artifactId> <version>4.8.0</version> <!-- 4.8.0+ 适配 Spring Boot 3 --> </dependency>
4)替换不兼容依赖
  • Spring Boot 3 移除了 javax.* 包,替换为 jakarta.*(核心变更):
<!-- 原 JAXB 依赖(javax) --> <dependency> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> </dependency> <!-- 替换为 jakarta 版本 --> <dependency> <groupId>jakarta.xml.bind</groupId> <artifactId>jakarta.xml.bind-api</artifactId> <version>4.0.1</version> </dependency> <dependency> <groupId>com.sun.xml.bind</groupId> <artifactId>jaxb-impl</artifactId> <version>4.0.2</version> <scope>runtime</scope> </dependency>

校验相关依赖(如 Hibernate Validator):

<!-- Spring Boot 3 中 validator 已适配 jakarta --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency>
2. 修改配置文件
(1)移除 / 替换过时配置

Spring Boot 3 废弃了部分配置项,需调整 application.yml/application.properties

  • server.servlet.context-path 改为 server.servlet.context-path(无变化,但需检查其他配置);
  • 数据源配置无核心变化,但需确保数据库驱动适配 JDK 17(如 MySQL 驱动升级到 8.0.30+):
spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/ruoyi?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 username: root password: root
(2)调整日志配置(可选)

Spring Boot 3 对日志框架的适配无大变化,但需确保 logback.xml 中无 javax.* 相关引用。

3. 代码层面兼容修改
(1)替换 javaxjakarta 导入

项目中所有 import javax.xxx 需替换为 import jakarta.xxx,核心场景:

// 原导入 import javax.validation.Valid; import javax.validation.constraints.NotNull; import javax.annotation.PostConstruct; // 替换为 import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; import jakarta.annotation.PostConstruct;

Servlet 相关:HttpServletRequestHttpServletResponse 等(若直接导入):

// 原导入 import javax.servlet.http.HttpServletRequest; // 替换为 import jakarta.servlet.http.HttpServletRequest;
2)调整 Spring Security 配置(关键)

Spring Boot 3 对应 Spring Security 6.x,若依的权限模块需适配:

三、测试验证

总结

  • WebSecurityConfigurerAdapter 已被废弃,改为通过 SecurityFilterChain 配置:
  • 若使用 Redis,Spring Data Redis 3.x 无核心 API 变化,但需确保序列化方式兼容;
  • 若依的定时任务、代码生成器等模块,需检查是否有 javax 相关引用,逐一替换。
  • 编译项目:执行 mvn clean compile,修复所有编译错误(主要是依赖缺失、导入错误);
  • 核心前提:升级 JDK 到 17+,替换所有 javax.* 依赖为 jakarta.*
  • 关键步骤:升级 Spring Boot 3 父依赖、适配 Spring Security 6 配置、替换代码中 javax 导入;
  • 验证重点:编译无错误、启动无异常、核心功能正常,是升级成功的核心标准。
  • 启动项目:检查启动日志,修复 Bean 初始化失败、配置加载异常等问题;
  • 功能测试:验证登录、菜单、权限、数据 CRUD 等核心功能是否正常;
  • 兼容性测试:验证第三方集成(如 OSS、短信、支付)是否适配 JDK 17 + Spring Boot 3。
// 原配置方式(Spring Boot 2) @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { // 权限配置 } } // 升级后(Spring Boot 3/Security 6) @Configuration @EnableWebSecurity public class SecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(auth -> auth .requestMatchers("/login", "/captcha").permitAll() .anyRequest().authenticated() ) .formLogin(form -> form .loginProcessingUrl("/login") .successHandler(authenticationSuccessHandler) .failureHandler(authenticationFailureHandler) ) .logout(logout -> logout .logoutUrl("/logout") .logoutSuccessHandler(logoutSuccessHandler) ) .csrf(csrf -> csrf.disable()); // 若依默认关闭CSRF,需适配新写法 return http.build(); } }
(3)其他兼容调整
升级后的源码下载:

https://gitee.com/ruoyieleadmin/ruoyi-ele-admin

    Read more

    异步编程实战:构建高性能Python网络应用

    异步编程实战:构建高性能Python网络应用

    目录 摘要 1 异步编程:为什么它是现代网络应用的必然选择 1.1 同步架构的瓶颈与异步架构的优势 2 核心技术原理深度解析 2.1 asyncio事件循环:异步编程的发动机 2.2 aiohttp框架架构解析 3 异步数据库驱动实战 3.1 异步数据库连接池管理 3.2 多数据库支持与连接池优化 4 WebSocket实时通信实战 4.1 构建高性能WebSocket服务器 4.2 实时数据推送与流处理 5 企业级实战案例 5.1 构建异步API网关 6 性能优化与故障排查 6.1 性能优化实战技巧 6.2 常见故障排查指南 7 总结与展望 7.1

    By Ne0inhk
    C++从入门到起飞之——AVL树 全方位剖析!

    C++从入门到起飞之——AVL树 全方位剖析!

    🌈个人主页:秋风起,再归来~ 🔥系列专栏:C++从入门到起飞           🔖克心守己,律己则安 目录 1. AVL的概念 2. AVL树的实现  2.1 AVL树的结构  2.2 AVL树的插⼊ >AVL树插⼊⼀个值的⼤概过程 >平衡因⼦更新 >插⼊结点及更新平衡因⼦的代码实现 2.3 旋转 2.3.1 旋转的原则 2.3.2 右单旋  2.3.3 右单旋代码实现 2.3.4 左单旋 2.

    By Ne0inhk

    用 Python 批量下载全量 A 股历史行情数据:基于 AKShare 的高效实践

    关键词:AKShare, A股数据, 股票历史行情, 量化分析, Python 金融, 断点续传 适用读者:量化交易初学者、金融数据分析师、Python 爱好者、学术研究者 💡 为什么需要本地化 A 股历史数据? 在量化投资、策略回测、因子挖掘等场景中,高质量、完整、本地存储的历史行情数据是不可或缺的基础。然而: * 商业数据接口(如 Wind、Tushare Pro)往往收费或有调用限制; * 免费接口(如早期 Tushare)可能不稳定或字段不全; * 网页爬虫易被反爬,维护成本高。 幸运的是,开源项目 AKShare 提供了免费、稳定、覆盖全面的中国金融市场数据接口,包括: * A 股日线、分钟线 * 指数、基金、期货、期权

    By Ne0inhk

    C++中的策略模式进阶

    1、非修改序列算法 这些算法不会改变它们所操作的容器中的元素。 1.1 find 和 find_if * find(begin, end, value):查找第一个等于 value 的元素,返回迭代器(未找到返回 end)。 * find_if(begin, end, predicate):查找第一个满足谓词的元素。 * find_end(begin, end, sub_begin, sub_end):查找子序列最后一次出现的位置。 vector<int> nums = {1, 3, 5, 7, 9}; // 查找值为5的元素 auto it = find(nums.begin(

    By Ne0inhk