💼 求职意向:本人目前正在积极寻找新的工作机会,欢迎各位大佬推荐或内推!🤝
📝 能力简述:详细的技术栈、项目经验及过往履历请见我的 Gitee 简历。同时,我也在持续更新技术博客,希望能通过分享与大家共同进步。
📄 我的简历Gitee 简历链接


如果有觉得此文对你有帮助,烦请 给项目 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
  • 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测试

  1. 在pom.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>
    
  2. 在maven-compiler-plugin中添加annotationProcessorPaths

    					<annotationProcessorPaths>
                            <path>
                                <groupId>org.openjdk.jmh</groupId>
                                <artifactId>jmh-generator-annprocess</artifactId>
                                <version>1.37</version>
                            </path>
                        </annotationProcessorPaths>
    
  3. 编写测试代码

    package 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();
        }
    }
    
    
  4. 编译并打包
    mvn clean package -pl renren-api -DskipTests -am
    此步一定需要做,否则报错:
    ERROR: Unable to find the resource: /META-INF/BenchmarkList JMH

  5. 执行性能测试

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐