💼 求职意向 :本人目前正在积极寻找新的工作机会,欢迎各位大佬推荐或内推!🤝
📝 能力简述 :详细的技术栈、项目经验及过往履历请见我的 Gitee 简历 。同时,我也在持续更新技术博客,希望能通过分享与大家共同进步。
📄 我的简历 :Gitee 简历链接
文章目录
- 为什么重构?
- 重构概览:技术栈全景
- 重构清单
-
- [📚 项目说明](#📚 项目说明)
- [🔥 Latest Updates](#🔥 Latest Updates)
- 性能对比:虚拟线程带来的质变
- 项目价值
- 未来规划
- 欢迎贡献
- 附录
如果有觉得此文对你有帮助,烦请 给项目 renren-security 点个star
为什么重构?
renren-security 一直是我心中最优秀的轻量级 Java 快速开发平台之一。它基于 Spring Boot、Shiro 和 Vue3 构建,凭借"极低门槛、拿来即用"的特性,成为了无数开发者交付项目的利器。
然而,随着 Spring Boot 4.0 的正式发布以及 Java 21 成为新的事实标准,原有技术栈在高并发、低延迟的现代应用需求下面临显著瓶颈。为了将这套经典的权限系统带入现代 Java 时代,基于 renren-security 5.5.0 版本,独自完成这次深度的技术重构。
本次重构升级的核心目标不仅仅是版本号的更迭,而是要利用虚拟线程(Virtual Threads)榨干服务器性能,并解决 Spring Boot 4 生态迁移中的各种"硬骨头"。
重构概览:技术栈全景
本次重构涵盖了语言底层、核心框架、数据持久化及中间件适配的全链路升级,重要修改项如下:
| 核心组件 | 原版本 | 新版本 | 核心变化与优势 |
|---|---|---|---|
| 基础框架 | Spring Boot 3.x | Spring Boot 4.0.0 | 适配 Jakarta EE 11+,引入新特性 |
| 运行时 | Java 17 | Java 21 (LTS) Java 25 (LTS) | 启用虚拟线程,提升并发吞吐量 |
| ORM 框架 | MyBatis-Plus 3.5.x | 3.5.15 (Spring boot 4适配版) | 依赖重构,拦截器模块化 |
| 数据源 | Druid Starter | Druid 1.2.27 (重构版) | 手动适配 Spring boot 4 包路径变更 |
| 数据库 | MySQL (默认) | H2 (默认) | 增强多数据库支持,降低上手门槛 |
| 工具库 | hutool 5.8.29 | 5.8.42 | |
| API DOC | springdoc 2.8.4 | 2.8.14 | |
| 模块化设计 | spring-boot-starter-web | 以下组件需要单独按模块引用 spring-boot-starter-quartz spring-boot-starter-aop spring-boot-starter-jdbc | Spring boot 4采用了a new modular design, 详见# JAVA 21 & Spring Boot 4 学习--迁移指南 Migration Guide |
| 虚拟线程 | 默认开启 | **Java 21 (LTS) **中正式发布 JVM 层面实现的用户态线程 | |
| 新特性验证 | 优雅 API 版本控制 程序化 Bean 注册 声明式HTTP客户端 | JAVA新特性测试验证 |
重构清单
详见 项目 renren-security 的readme.md
📚 项目说明
- 本项目fork renren-security, 基于5.5.0版本,测试验证springboot 4.x 及 spring-ai 2.x相关的功能
- renren-security是一个轻量级的,前后端分离的Java快速开发平台,能快速开发项目并交付【接私活利器】
- 采用SpringBoot4.x、Shiro、MyBatis-Plus、Vue3、TypeScript、Element Plus、Vue Router、Pinia、Axios、Vite框架,开发的一套权限系统,极低门槛,拿来即用。设计之初,就非常注重安全性,为企业系统保驾护航,让一切都变得如此简单。
- 提供了代码生成器,只需编写30%左右代码,其余的代码交给系统自动生成,可快速完成开发任务
- 支持MySQL、PostgreSQL、H2等主流数据库【理论上支持达梦、Oracle、SQL Server,但在springboot 4下未测试】
🔥 Latest Updates
- 2025-12-23
- 升级java 版本至21,默认使用25
- 升级springboot 最新版4.0.0, 参考 JAVA 21 & Spring Boot 4 学习--迁移指南 Migration Guide
- mybatisplus调整
- 升级 mybatisplus 3.5.15 【mybatis-plus-spring-boot4-starter】, 因为SpringBoot4 需要 ^3.5.13,详见mybatis-plus
- 增加mybatis-plus-jsqlparser 依赖,因为mybatisplus ^3.5.9 需要单独引用,BlockAttackInnerInterceptor及PaginationInnerInterceptor迁移至此模块
- Druid调整
- 因为druid spring starter还未提供针对springboot 4的支持,主要是因为springboot 包结构发生的变化【org.springframework.boot.autoconfigure. -> org.springframework.boot..autoconfigure】,导致编译报错,所以虽然保留了druid-spring-boot-3-starter依赖,但重构了com.alibaba.druid.spring.boot3.autoconfigure下面的2个类
- druid 版本升级至1.2.27
- 增加针对H2的支持,并且renren-admin,renren-api中默认使用H2作为数据库启动
- hutool版本升级至5.8.42
- springdoc版本升级至2.8.14
- 在springboot 4下,以下组件需要单独引用
- spring-boot-starter-quartz
- spring-boot-starter-aop 在springboot 4下调整为spring-boot-starter-aspectj
- spring-boot-starter-jdbc
- 添加了一些针对Springboot 4新特性的测试
- 优雅 API 版本控制
- 程序化 Bean 注册(BeanRegistrar)
- 声明式HTTP客户端 HttpExchange
性能对比:虚拟线程带来的质变
为了验证升级效果,对核心的用户查询接口(包含数据库 I/O 操作)进行了压测对比:
| 指标 | 传统线程模型 (Spring Boot 3 + Java 17) | 虚拟线程模型 (Spring Boot 4 + Java 21) | 提升幅度 |
|---|---|---|---|
| 吞吐量 (Req/s) | ~1,200 | ~15,500 | 12x |
| 平均延迟 | 85ms | 12ms | 降低 86% |
| 资源利用率 | CPU 闲置与线程上下文切换频繁 | CPU 利用率稳定在 90%+ | - |
结论: 在 I/O 密集型的权限管理系统中,虚拟线程通过"遇阻塞自动挂起"的机制,实现了线程的轻量化、调度的智能化、资源的高效化,真正将硬件性能释放到极致。
项目价值
本次升级后的 renren-security 不仅支持最新的 Java 与 Spring 技术栈,还具备更强的扩展性与现代化开发体验。它将继续作为一款"轻量级 Java 快速开发平台",帮助开发者快速构建安全、稳定、可交付的后台系统。
- 对于架构师: 它证明了 Spring Boot 4 + Virtual Threads 是下一代高并发应用的黄金搭档。
- 对于开发者: 它保留了代码生成器"生成 70% 代码"的杀手级特性,同时拥有了更强劲的内核。
未来规划
- 集成 Spring AI 2.x,支持 AI 驱动的智能权限推荐
欢迎贡献
技术升级从来不是一蹴而就,但每一次对技术边界的探索,都是为了让更多开发者"少写代码,多做业务"。
希望这次升级能为你带来更流畅的开发体验。
如果你也在使用 renren-security,欢迎提交 PR 或 issue,一起打造更强大的开源生态!
附录
如何使用JMH测试
-
在pom.xml中添加依赖
xml<dependency> <groupId>org.openjdk.jmh</groupId> <artifactId>jmh-core</artifactId> <version>1.37</version> </dependency> <dependency> <groupId>org.openjdk.jmh</groupId> <artifactId>jmh-generator-annprocess</artifactId> <version>1.37</version> <scope>provided</scope> </dependency> -
在maven-compiler-plugin中添加annotationProcessorPaths
xml<annotationProcessorPaths> <path> <groupId>org.openjdk.jmh</groupId> <artifactId>jmh-generator-annprocess</artifactId> <version>1.37</version> </path> </annotationProcessorPaths> -
编写测试代码
javapackage io.renren.test; import org.openjdk.jmh.annotations.*; import org.openjdk.jmh.infra.Blackhole; import org.openjdk.jmh.runner.Runner; import org.openjdk.jmh.runner.RunnerException; import org.openjdk.jmh.runner.options.Options; import org.openjdk.jmh.runner.options.OptionsBuilder; import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.time.Duration; import java.util.concurrent.TimeUnit; // 1. 定义状态:表示这个实例会在所有线程间共享(或者每个线程一个实例) @State(Scope.Benchmark) // 2. 预热配置:进行 3 轮预热,让 JVM 编译优化到位 @Warmup(iterations = 3, time = 5, timeUnit = TimeUnit.SECONDS) // 3. 测量配置:正式测量 5 次,每次持续 10 秒 @Measurement(iterations = 5, time = 10, timeUnit = TimeUnit.SECONDS) // 4. 测试模式:输出吞吐量、平均时间等 @BenchmarkMode(Mode.All) // 5. 输出时间单位 @OutputTimeUnit(TimeUnit.MILLISECONDS) // 6. Fork 1 个进程进行测试 @Fork(1) @Threads(100) public class JMHTest { // 在这里初始化 HTTP 客户端,只会执行一次 private HttpClient client; @Setup(Level.Trial) // 在整个测试开始前执行 public void setUp() { this.client = HttpClient.newBuilder() .connectTimeout(Duration.ofSeconds(10)) .build(); } // 7. 核心测试方法 @Benchmark public void testGetUserApi(Blackhole blackhole) throws Exception { // 构建请求 HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("http://localhost:8081/renren-api/api/userId")) .header("token","e926bc0e600546e6844ee0bf3d2e0c47") .timeout(Duration.ofSeconds(5)) .GET() .build(); // 发送请求并消费结果(使用 Blackhole 防止 JVM 优化掉结果) HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); blackhole.consume(response.body()); // 必须消费结果,否则 JVM 可能会忽略这行代码 } // 主方法,用于直接运行 public static void main(String[] args) throws RunnerException { Options opt = new OptionsBuilder() .include(JMHTest.class.getSimpleName()) .build(); new Runner(opt).run(); } } -
编译并打包
mvn clean package -pl renren-api -DskipTests -am此步一定需要做,否则报错:
ERROR: Unable to find the resource: /META-INF/BenchmarkList JMH -
执行性能测试