# 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 的全部威力!** 💪
---