Caffeine 是Java高性能堆内本地缓存库Guava Cache 的继任者Spring5 推荐本地缓存实现核心亮点是W-TinyLFU淘汰算法高并发、高命中率适合单机热点数据缓存。本质JVM内存缓存单机有效重启丢失多实例之间数据不自动同步常和 Redis 组成多级缓存Caffeine一级Redis二级。一、核心原理W-TinyLFUWindow TinyLFUGuava Cache 用 LRU只看最近访问容易被一次性批量查询的冷数据污染缓存W-TinyLFU同时兼顾访问频率最近访问时间命中率接近理论最优 Belady 算法。三段队列Window 窗口队列新写入数据先进窗口区保护新热点防止一次性大量冷数据直接淘汰老热点Probation 候选淘汰队列窗口满了移到这里候选区里对比访问频率淘汰低频数据Protected 保护队列候选区中被再次访问的数据升级到此尽量保留热点保护队列满则降级回候选区频率统计用Count-Min Sketch用少量内存近似统计访问频次不存完整计数器内存开销很小。并发模型读操作几乎无锁写操作CAS RingBuffer异步批量更新访问统计极大降低锁竞争吞吐量远超Guava Cache。二、三大缓存APICacheK,V基础缓存getIfPresentget(key, loader)不存在时同步加载LoadingCacheK,V继承Cache自动加载get不存在时自动调用loader加载AsyncLoadingCacheK,V异步加载返回CompletableFutureIO阻塞场景推荐三、淘汰/过期策略可组合使用1. 基于容量生产必须配置防止OOMmaximumSize(long)最大缓存条目数超限按W-TinyLFU淘汰maximumWeight(long) weigher()按对象权重淘汰比如按value字节大小2. 基于时间过期expireAfterWrite(5, TimeUnit.MINUTES)写入后5分钟过期固定TTLexpireAfterAccess(5, TimeUnit.MINUTES)最后一次访问起计时闲置超时自动清理适合不常访问数据refreshAfterWrite(1, TimeUnit.MINUTES)后台异步刷新访问key时如果超过设定时间异步去加载新值旧值先返回不会阻塞用户请求缓解缓存雪崩⚠️ refreshAfterWrite 不是过期只是主动刷新不会主动删除旧key3. 基于引用GC回收谨慎使用weakKeys()key弱引用GC回收weakValues()value弱引用softValues()value软引用内存不足时JVM自动回收兜底防OOM附加能力removalListener缓存被淘汰/删除时回调日志、监控recordStats()开启统计可获取命中率、命中数、加载耗时、淘汰数量等指标线上监控必备四、Maven依赖dependency groupIdcom.github.benmanes.caffeine/groupId artifactIdcaffeine/artifactId version3.1.8/version /dependency五、基础代码示例import com.github.benmanes.caffeine.cache.Caffeine; import com.github.benmanes.caffeine.cache.LoadingCache; import java.util.concurrent.TimeUnit; public class CaffeineDemo { public static void main(String[] args) { // LoadingCache自动加载版本 LoadingCacheString, String cache Caffeine.newBuilder() .maximumSize(10000) // 最多1万条 .expireAfterWrite(5, TimeUnit.MINUTES) // 写入5分钟过期 .refreshAfterWrite(1, TimeUnit.MINUTES) // 写入1分钟后访问时异步刷新 .recordStats() // 开启统计 .removalListener((key, val, cause) - { System.out.println(缓存移除key key ,原因: cause); }) // 缓存缺失时加载函数一般查DB/远程接口 .build(key - loadFromDb(key)); // 使用 String val cache.get(user:1001); System.out.println(val); // 获取统计信息 System.out.println(cache.stats()); } private static String loadFromDb(String key) { // 模拟数据库查询 return key _data; } }六、适用 不适用场景✅ 适合单机、低延迟热点数据配置、字典、基础资料读多写少数据体量可控可放入JVM堆多级缓存架构作为Redis前一级本地缓存减少Redis压力❌ 不适合分布式多实例要求缓存强一致各实例本地缓存独立更新会脏读超大数据集无法全部放入JVM堆需要持久化、跨服务共享缓存用Redis多级缓存经典链路请求 → Caffeine本地缓存命中直接返回 → 未命中查Redis → Redis未命中查DB回写Redis Caffeine七、Caffeine vs Guava Cache vs RedisCaffeineGuava CacheRedis位置JVM本地内存JVM本地内存独立中间件网络访问淘汰算法W-TinyLFULRULRU / LFU等性能极高中等受网络影响多实例共享❌ 不共享❌ 不共享✅ 全局共享持久化❌❌✅ RDB/AOF八、生产避坑重点必须设置maximumSize只配置expire不设上限会无限涨内存导致OOM分布式场景Caffeine只做短期兜底缓存配合消息广播/Canal主动失效本地缓存同时TTL做兜底容忍短暂脏读refreshAfterWrite只是异步刷新不能解决缓存穿透空值记得缓存缓存key最好不可变正确重写equals/hashCode统计指标命中率一定要监控命中率过低说明缓存策略不合理软引用softValues慎用GC频繁会严重影响性能优先用maximumSize控制。九、Caffeine 缓存Java本地缓存库最新正式版3.2.42026-05-04 发布项目地址GitHub - ben-manes/caffeine: A high performance caching library for Java · GitHubMavendependency groupIdcom.github.ben-manes.caffeine/groupId artifactIdcaffeine/artifactId version3.2.4/version /dependencyGradleimplementation com.github.ben-manes.caffeine:caffeine:3.2.4Kotlin DSLimplementation(com.github.ben-manes.caffeine:caffeine:3.2.4) JDK版本硬性要求3.x 系列JDK 113.2.4 需要 Java11 及以上2.x 系列JDK 8最新稳定2.9.3老Java8项目用这个配套扩展包同版本!-- JSR107 JCache规范实现需要JCache注解时引入 -- dependency groupIdcom.github.ben-manes.caffeine/groupId artifactIdjcache/artifactId version3.2.4/version /dependency !-- Guava适配器兼容Guava Cache代码迁移 -- dependency groupIdcom.github.ben-manes.caffeine/groupId artifactIdguava/artifactId version3.2.4/version /dependency版本选择建议SpringBoot3 / JDK17/21新项目 →3.2.4SpringBoot2、JDK8老项目 →2.9.3不要强行上3.x生产优先用正式Release不要用SNAPSHOT快照版之前示例写的 3.1.8 属于旧版建议新项目升级到3.2.4修复了一些并发、内存统计的bug。十、SpringBoot 4.x Caffeine 支持说明✅Spring Boot 4.x 原生完整支持 Caffeine内置CaffeineCacheManager自动装配Cacheable、CacheEvict等 Spring Cache 注解全部可用和 SpringBoot3 使用方式几乎一样。SpringBoot4 基线JDK17正好匹配 Caffeine 3.x 的最低要求JDK11推荐直接用Caffeine 3.2.41、SpringBoot4 托管版本SpringBoot4 的 dependency-management 自带管理 Caffeine 3.2.x不写 version 也能自动拉取对应版本 你也可以显式指定3.2.4当前最新正式版完全兼容。Maven依赖!-- Spring Cache starter -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-cache/artifactId /dependency !-- Caffeine本地缓存 -- dependency groupIdcom.github.ben-manes.caffeine/groupId artifactIdcaffeine/artifactId version3.2.4/version /dependencyGradleimplementation org.springframework.boot:spring-boot-starter-cache implementation com.github.ben-manes.caffeine:caffeine:3.2.42、两种配置方式SpringBoot4通用方式1yaml配置简单场景CaffeineSpec语法spring: cache: type: caffeine cache-names: userDict,areaDict caffeine: spec: maximumSize10000,expireAfterWrite5m,refreshAfterWrite1mspec参数说明最大1w条写入5分钟过期访问时1分钟后异步后台刷新方式2自定义Caffeine Bean推荐可自定义removalListener、统计、复杂逻辑import com.github.benmanes.caffeine.cache.Caffeine; import org.springframework.cache.CacheManager; import org.springframework.cache.caffeine.CaffeineCacheManager; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.cache.annotation.EnableCaching; import java.util.concurrent.TimeUnit; Configuration EnableCaching public class CaffeineCacheConfig { Bean public CacheManager cacheManager() { CaffeineCacheManager cacheManager new CaffeineCacheManager(); // 构造Caffeine实例 CaffeineObject, Object caffeineBuilder Caffeine.newBuilder() .maximumSize(10000) .expireAfterWrite(5, TimeUnit.MINUTES) .refreshAfterWrite(1, TimeUnit.MINUTES) .recordStats() // 开启缓存指标统计命中率、淘汰数 .removalListener((key, val, cause) - { // 缓存淘汰回调可埋点日志 }); cacheManager.setCaffeine(caffeineBuilder); // 可选不允许缓存null防止缓存穿透 cacheManager.setAllowNullValues(false); return cacheManager; } }3、SpringBoot4 注意事项JDK版本底线SpringBoot4 最低 JDK17Caffeine3.2.4 在 JDK17/21/23 全部稳定不要用Caffeine2.x2.x是JDK8版本不建议在Boot4混用自动装配逻辑不变classpath存在caffeine包SpringBoot自动实例化CaffeineCacheManager手动声明CacheManager Bean则优先使用自定义BeanGraalVM Native镜像SpringBoot4支持native打包Caffeine3.x对GraalVM支持良好少量场景需要添加native hint注解使用和Boot3完全一致Cacheable(value userDict, key #id) public UserDTO getUser(Long id) { // 查DB逻辑 }4、常见坑refreshAfterWrite仅访问时触发异步刷新不会主动后台轮询刷新旧值会继续返回不会阻塞请求setAllowNullValues(false)开启后方法返回null会抛异常想缓存空值来防穿透需要设置trueCaffeine是单机本地缓存分布式环境多实例会数据不一致适合多级缓存Caffeine Redis架构5、版本选型建议SpringBoot4.0 /4.1 → Caffeine3.2.4推荐不要混用 caffeine 2.x2.x面向JDK8在JDK17虽然能跑但缺少新特性和bug修复