# JetCachePlugin **Repository Path**: tencent8/jet-cache-plugin ## Basic Information - **Project Name**: JetCachePlugin - **Description**: JetCachePlugin封装阿里JetCache,专为 JFinal(纯Java)打造“一行接入、本地(Caffeine)+远程(Redis)按需开启 / 关闭、cached风格、到期前可自动刷新缓存、防击穿、高频访问无忧”。 - **Primary Language**: Java - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-12-18 - **Last Updated**: 2025-12-18 ## Categories & Tags **Categories**: Uncategorized **Tags**: JFinal, JetCache, 多级缓存, 防击穿, Redis ## README # JetCachePlugin ### JetCachePlugin封装阿里JetCache,专为 JFinal(纯Java)打造“一行接入、本地(Caffeine)+远程(Redis)按需开启关闭、cached风格、到期前可自动刷新缓存、防击穿、高频访问无忧”。 - JetCachePlugin 在纯 JFinal或Java 项目中,一键启用阿里 JetCache 多级缓存能力 ### 🔥 你是否羡慕 Spring 项目能用 JetCache一个注释就搞定,而 JFinal 却只能手写重复的put,get缓存逻辑? - 想用 本地 + Redis 多级缓存,但不想引入 Spring? - 担心 热点 key 失效导致缓存击穿,DB 被打爆? - 厌倦了重复写 if (cache == null) loadFromDB() 的样板代码? - 知道 [alibaba/jetcache](https://github.com/alibaba/jetcache) 很强,但被繁琐的接入方案劝退? ### 现在,这些问题一次性解决! - ✅ JetCachePlugin —— 将阿里 JetCache 的强大能力,无缝注入 JFinal 项目,一行代码接入! - ✅ 为什么选择它?—— 站在巨人肩膀上,为 JFinal 而生 ### 优势 说明 ------ ------ - 🧠 基于阿里 JetCache 内核 底层使用 [JetCache 2.7.8+](https://github.com/alibaba/jetcache),经过阿里内部及数千企业验证,稳定可靠 - 🚫 通过精简封装,纯 Java 运行,完美契合 JFinal 极简哲学 - ⚡ 自动多级缓存 本地(Caffeine) + 远程(Redis via Lettuce)自动串联,先读快缓存,再读持久缓存 - 🛡️ 天然防缓存击穿 支持 syncLocal = true(默认开启),并发请求同一 miss key 时,仅一个线程查 DB,其余等待结果 - 🧩 JFinal 风格 API me.add(new JetCachePlugin("default")) 初始化,JetCacheKit.cached(...)、JetCacheKit.get(...)、JetCacheKit.put(...) 使用,符合 JFinal 开发者直觉 - 📦 轻量集成 仅依赖 jetcache-core + jetcache-redis-lettuce + caffeine,无额外负担 ### 🚀 快速上手(真的只要一行!) ### Step 1:添加 Maven 依赖 Maven 引用(via JitPack) ```xml jitpack.io https://jitpack.io com.github.seallon jet-cache-plugin v1.0.0 ``` - 💡 实际底层依赖: - com.alicp.jetcache:jetcache-core - com.alicp.jetcache:jetcache-redis-lettuce - com.github.ben-manes.caffeine:caffeine ### Step 2:初始化(在 JFinalConfig.configPlugin(Plugins me) 中) ``` public void configPlugin(Plugins me) { me.add(new JetCachePlugin("default") //.redisOnly() //仅启用Redis缓存 //.setLocalLimit(500) //本地缓存(Caffeine)的最大条目数限制 //.setLocalExpireSeconds(600) //本地缓存(Caffeine)中每个条目的过期时间(秒) //.setRemoteExpireSeconds(3600) //远程缓存(Redis)中每个条目的过期时间(秒) //.setDefaultCacheConfig(new DefaultCacheConfig(100, 1800L, 3600L, false, 0.2, 120L)) //设置全局默认新建缓存配置 //.setAutoCreateCache(true) //是否允许在调用时自动创建不存在的缓存实例,是:用DefaultCacheConfig配置自动创建 //.enableRandomTtl(300) //是否启用“随机 TTL”功能,用于缓解缓存雪崩问题 //.setGlobalMinRefreshTtlSeconds(120L) //全局最小自动刷新 TTL(用于缓存预热/提前刷新机制),单位:秒 //.setMaxAllowedTtlSeconds(7*24*3600L) //全局最大允许的缓存 TTL(Time-To-Live,生存时间)防止缓存长期不释放,单位:秒 ); } ✅ 支持多种模式: JetCachePlugin() → 仅本地缓存(开发/测试/不需要远程缓存) JetCachePlugin("default") → 默认 Redis JetCachePlugin("redis://:pwd@host:6379/2") → 指定 Redis ``` ### Step 3:使用缓存( anywhere in your code ) ``` //手动创建缓存(没开启自动创建缓存时,必须手动创建) JetCacheKit.createCache("course"); //默认缓存策略 JetCacheKit.createCache("course", 100, 20, 40); //默认区域“default”,自定义缓存策略 JetCacheKit.createCache("default", "course", 100, 20, 40); //完全自定义缓存策略 // ================自动走多级缓存 + 防击穿加载================ //1.带加载器的cached风格(无需手动put),单独为该缓存开启自动刷新缓存 CourseInfo courseInfo = JetCacheKit.cached("courseInfo", "1", () -> CourseInfo.dao.queryFirst( Dict.create() //.select("courseName, viewCount") .eq("id", 1) ), // 仅当缓存未命中时执行加载数据库 JetCacheKit.CachedOptions.of().autoRefresh(true) //单独为该缓存开启自动刷新缓存 ); //2.带加载器的cached风格(无需手动put),单独设置缓存时间60s CourseInfo courseInfo = JetCacheKit.cached("courseInfo", "1", 60, //单独设置缓存时间60s () -> CourseInfo.dao.queryFirst( Dict.create() //.select("courseName, viewCount") .eq("id", 1) ) // 仅当缓存未命中时执行加载数据库 ); //3.带加载器的cached风格(无需手动put),完全使用默认缓存策略 CourseInfo courseInfo = JetCacheKit.cached("courseInfo", "1", () -> CourseInfo.dao.queryFirst( Dict.create() //.select("courseName, viewCount") .eq("id", 1) ) // 仅当缓存未命中时执行加载数据库 ); // 手动写入缓存(自动同步到本地 + Redis) JetCacheKit.put("courseInfo", "1", courseInfo); //使用默认缓存时间 JetCacheKit.put("courseInfo", "1", courseInfo, 120); //指定缓存时间 // 手动获取缓存(先本地 ,本地没有再 Redis,没有就返回null) JetCacheKit.get("courseInfo", "1", courseInfo); // 移除缓存 JetCacheKit.evict("courseInfo", "1"); // 清除单个缓存项,根据cacheName 和 key组合清除 JetCacheKit.evictAll("courseInfo"); // 空指定 cacheName 下的所有缓存(本地 + 远程) // 同步刷新缓存:删除并立即重新加载 JetCacheKit.refresh("courseInfo", "1", () -> CourseInfo.dao.queryFirst( Dict.create() //.select("courseName, viewCount") .eq("id", 1) ) ); // 同步刷新缓存,指定缓存时间:删除并立即重新加载 JetCacheKit.refresh("courseInfo", "1", 120 () -> CourseInfo.dao.queryFirst( Dict.create() //.select("courseName, viewCount") .eq("id", 1) ) ); // 异步刷新缓存:删除并立即重新加载 JetCacheKit.refreshAsync("courseInfo", "1", () -> CourseInfo.dao.queryFirst( Dict.create() //.select("courseName, viewCount") .eq("id", 1) ) ); // 异步刷新缓存,指定缓存时间:删除并立即重新加载 JetCacheKit.refreshAsync("courseInfo", "1", 120 () -> CourseInfo.dao.queryFirst( Dict.create() //.select("courseName, viewCount") .eq("id", 1) ) ); // 获取 courseInfo 缓存命中率 MetricsSnapshot snap = JetCacheKit.getMetrics("courseInfo"); Console.log("courseInfo cache hit rate: {}%, avg load: {}ms", snap.getHitRate() * 100, snap.getAvgLoadMillis()); // 获取 所有 缓存命中率 Map snaps = JetCacheKit.getAllMetrics(); for(MetricsSnapshot snap : snaps.values()){ Console.log("courseInfo cache hit rate: {}%, avg load: {}ms", snap.getHitRate() * 100, snap.getAvgLoadMillis()); } ``` > 🔥 **关键机制**:JetCachePlugin 默认开启 `syncLocal`, > 即使 1000 个线程同时请求 `"123"`,**只有一个线程查数据库,其余线程阻塞等待结果**,彻底杜绝雪崩! --- ### 🛠 高级能力(JetCache 原生支持) - ✅ 自定义序列化(Kryo / Hessian / JSON) - ✅ 缓存统计监控(命中率、加载耗时) - ✅ 异步刷新(refreshAfterWrite) - ✅ 多 Redis 实例支持(通过 URI 指定) - ✅ 优雅关闭(纯java调用:JetCacheManager.shutdown()) --- ### 📊 推荐指数 & 易用指数 | 维度 | 评分(⭐️ 满分 5 星) | 说明 | |------|------------------|------| | **推荐指数** | ⭐️⭐️⭐️⭐️⭐️ | 让 JFinal 用户平权享受 JetCache 企业级能力 | | **易用指数** | ⭐️⭐️⭐️⭐️⭐️ | 初始化 1 行,使用 1 行,无学习成本 | | **性能提升** | ⭐️⭐️⭐️⭐️✨ | 本地命中率 >90% 时,QPS 提升 5~10 倍 | | **稳定性** | ⭐️⭐️⭐️⭐️⭐️ | 基于 JetCache 成熟内核,生产验证 | | **兼容性** | ⭐️⭐️⭐️⭐️⭐️ | JFinal 3.x ~ 5.x,Java 8+,无 Spring 冲突 | --- ### 🌐 开源地址 - **Gitee(国内推荐)**: [https://gitee.com/tencent8/jet-cache-plugin](https://gitee.com/tencent8/jet-cache-plugin) - **Github **: [https://github.com/seallon/jet-cache-plugin](https://github.com/seallon/jet-cache-plugin) > 📣 **欢迎 Star、Fork、PR!如果你是 JFinal 或者纯Java 用户,这个插件将为你带来 Spring 项目同款缓存体验,却无需引入任何 Spring 依赖!** --- ### 💬 最后说一句 - **“JetCache 很强但有点复杂,JFinal(纯java)也可以一行接入。”** - > JetCachePlugin —— 不是重复造轮子,而是把顶级轮子装到 JFinal 的车上。 - > 一行代码,高频访问不崩,缓存击穿无忧,从此告别手写缓存胶水代码! --- **立即集成,让 JFinal 也能享受 JetCache 的全部威力!** 💪 ---