SpringCache官方文档
- 常见问题
- 使用redis作为存储cache,@CacheConfig:cacheNames未在key前增加前缀,不同实体key重复
未开启RedisCacheManager::setUsePrefix
- 不同cacheName如何配置不同的过期时间
springCache配置方法重写,继承CachingConfigurerSupport,重写bean cacheManager,在setCaches将不同cache配置不同的tts(仅可以保证cacheName已预定义的cache)
若所使用的cacheManager实现了方法getMissingCache(该方法在抽象类中返回为null,需各实现类自己实现),比如RedisCacheManager就实现了若预定义cache不存在,则新建cache,后续抽象类在调用该方法后,将返回的cahce和cacheName放入预定义的cahceMap中,供下次使用。该情况需要重写getMissingCache方法,在新建cache时候,根据不同的cacheName配置不同的tts
- 自定义SpringCache存储
若实现自定义存储(官方没有提供实现的),主要需要实现CacheManager和Cache
- CacheManager
继承AbstractCacheManager(扩展官方的可以继承官方实现类),实现自定义CacheManager
作用:管理所有使用的Cache信息,其实就是通过Map<CacheName, Cache>存储Cache,在SpringCache触发时,根据不同的CacheName找到其存储实体
CacheManager获取不同Cache主要逻辑
public Cache getCache(String name) {
Cache cache = this.cacheMap.get(name);
if (cache != null) {
return cache;
}
else {
// Fully synchronize now for missing cache creation...
synchronized (this.cacheMap) {
cache = this.cacheMap.get(name);
if (cache == null) {
//注意 在map中获取不到cache时,或调用该方法,此方法为实现类自己实现,若不返回新Cache则需要抛出错误
cache = getMissingCache(name);
if (cache != null) {
cache = decorateCache(cache);
this.cacheMap.put(name, cache);
updateCacheNames(name);
}
}
return cache;
}
}
}
- Cache
继承org.springframework.cache.Cache,实现springCache在处理各种情况下所需的原子方法
作用:除了各存储相关方法,getName也不能忽略,在某些CacheManger中,setCaches为List,而Map的key值是通过调用Cache::getName方法获取的,若在使用过程通过name找不到预定义的Cache,就会触发CacheManager的getMissingCache方法
- 实现原理
通过AOP实现注解拦截方法查询或注入缓存,具体可以翻下注解触发的源码
网友评论