如何在独立类中正确获取Caffeine缓存统计数据的最佳实践
是否存在可在独立类实现中调用Caffeine缓存的方法?
你当前的实现存在两个核心问题:
- 每次调用
caffeineConfig.build()都会生成一个全新的独立缓存实例,和CacheManager中实际承载业务数据的缓存完全不是同一个对象,既会造成不必要的内存浪费,也永远拿不到真实的缓存统计数据。 - 你的缓存配置类中初始化顺序错误:先调用
getCache("addresses")创建缓存,再设置Caffeine配置,会导致提前创建的缓存不会应用你定义的过期时间、统计开启规则,全部使用默认参数初始化。
符合最佳实践的实现方案
第一步:修正缓存配置初始化顺序
调整CacheManager的配置逻辑,先传入Caffeine配置,再创建目标缓存:
@Configuration @EnableCaching(mode = AdviceMode.ASPECTJ) public class CacheConfiguration { @Bean public Caffeine<Object, Object> caffeineConfig() { return Caffeine.newBuilder() .expireAfterWrite(1, TimeUnit.MINUTES) .recordStats(); } @Bean public CacheManager cacheManager(Caffeine<Object, Object> caffeine) { CaffeineCacheManager caffeineCacheManager = new CaffeineCacheManager(); // 先设置全局Caffeine配置,再初始化缓存 caffeineCacheManager.setCaffeine(caffeine); caffeineCacheManager.getCache("addresses"); return caffeineCacheManager; } }
第二步:直接注入Spring管理的实际缓存实例获取统计数据
不要注入Caffeine构建器重复build缓存,直接注入业务中实际使用的缓存实例,通过原生Caffeine缓存对象获取统计信息即可:
@Component public class RequestLoggingFilter extends AbstractRequestLoggingFilter { // 直接注入实际运行的addresses缓存 @Autowired private Cache addressesCache; @Override protected void afterRequest(HttpServletRequest request, String message) { // 仅在请求处理完成后才可记录Payload(内部使用ContentCachingRequestWrapper实现) this.logger.info(message); if (addressesCache instanceof CaffeineCache caffeineCache) { com.github.benmanes.caffeine.cache.Cache<Object, Object> nativeCache = caffeineCache.getNativeCache(); // 直接读取现有缓存实例的统计数据 this.logger.info("缓存命中次数:{}", nativeCache.stats().hitCount()); } } }
补充说明
- 如果你需要统计所有缓存的运行指标,可以直接注入
CacheManager实例,遍历cacheManager.getCacheNames()获取所有缓存对象,逐个转换为CaffeineCache读取统计数据即可。 - Caffeine的
build()方法仅需在缓存初始化阶段调用一次,运行时反复调用会生成完全独立的新缓存,不存储任何业务数据,没有实际业务价值。
内容的提问来源于stack exchange,提问作者MAMMIA
相关产品推荐
相关产品推荐

