com.google.common.cache实现本地缓存
com.google.common.cache 基础介绍
com.google.common.cache
是 Google Guava 库中的一个缓存工具包,用于实现本地缓存功能。其核心类包括 Cache
和 LoadingCache
,支持自动加载、过期策略、缓存淘汰等功能。
缓存创建与基本使用
通过 CacheBuilder
构建缓存实例,支持链式配置。以下是一个基础示例:
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;// 创建缓存实例
Cache<String, String> cache = CacheBuilder.newBuilder().maximumSize(100) // 最大缓存条目数.expireAfterWrite(10, TimeUnit.MINUTES) // 写入后10分钟过期.build();// 写入缓存
cache.put("key1", "value1");// 读取缓存(若不存在返回null)
String value = cache.getIfPresent("key1");
LoadingCache 自动加载
LoadingCache
在缓存未命中时自动通过 CacheLoader
加载数据,适合需要自动填充缓存的场景。
import com.google.common.cache.LoadingCache;
import com.google.common.cache.CacheLoader;LoadingCache<String, String> loadingCache = CacheBuilder.newBuilder().maximumSize(100).build(new CacheLoader<String, String>() {@Overridepublic String load(String key) {// 模拟从数据库加载数据return fetchFromDatabase(key);}});// 使用get方法触发自动加载
String value = loadingCache.get("key1");
缓存过期策略
Guava Cache 支持两种过期策略:
基于写入时间过期:
CacheBuilder.newBuilder().expireAfterWrite(5, TimeUnit.SECONDS) // 写入后5秒过期.build();
基于访问时间过期:
CacheBuilder.newBuilder().expireAfterAccess(10, TimeUnit.SECONDS) // 最后一次访问后10秒过期.build();
缓存淘汰策略
支持基于大小、权重、手动清理等淘汰方式:
// 基于大小淘汰
CacheBuilder.newBuilder().maximumSize(100) // 最多保留100个条目.build();// 基于权重淘汰(需定义weigher)
CacheBuilder.newBuilder().maximumWeight(1000).weigher((String key, String value) -> value.length()).build();// 手动清理单个条目
cache.invalidate("key1");// 清理所有条目
cache.invalidateAll();
监听器与统计信息
通过 RemovalListener
监听条目移除事件,并启用统计信息:
// 添加移除监听器
CacheBuilder.newBuilder().removalListener((RemovalNotification<String, String> notification) -> {System.out.println("Key " + notification.getKey() + " was removed due to " + notification.getCause());}).build();// 启用统计信息
Cache<String, String> cache = CacheBuilder.newBuilder().recordStats().build();// 获取命中率等信息
CacheStats stats = cache.stats();
double hitRate = stats.hitRate();
完整示例:缓存数据库查询
以下是一个结合数据库查询的完整示例:
LoadingCache<String, User> userCache = CacheBuilder.newBuilder().maximumSize(1000).expireAfterWrite(30, TimeUnit.MINUTES).build(new CacheLoader<String, User>() {@Overridepublic User load(String userId) {return userDao.findById(userId); // 模拟数据库查询}});// 使用缓存
User user = userCache.get("user123");
注意事项
- 线程安全:
Cache
和LoadingCache
是线程安全的,无需额外同步。 - 空值处理:默认不允许缓存
null
值,需在CacheLoader
中显式处理。 - 性能监控:通过
recordStats()
监控缓存命中率,优化缓存大小和过期时间。
通过上述配置和示例,可以灵活应对多种本地缓存需求。