? ? ?? Hibernate老鳥的話,對于Hibernate cache的精妙實(shí)現(xiàn)應(yīng)該都是非常了解,即便不了解其實(shí)現(xiàn)原理,也知道Hibernate cache非常的易用,集成EhCache,對于系統(tǒng)性能也有很好的提升。那我們來看看如易云的框架,如易云的框架基于Mybatis,Mybatis新版本中也集成了cache,并且也有開源的分布式cache集成(例如: Mybatis-Ignite? https://github.com/mybatis/ignite-cache?),但如易云在數(shù)據(jù)庫操作方面做了非常多的業(yè)務(wù)語義抽象(具體參見:創(chuàng)易-數(shù)據(jù)庫層設(shè)計(jì)?),對于cache,當(dāng)然一方面我希望在這個(gè)層面做下處理,另一方面就是 我之前在上家公司基于spring cache做的獨(dú)有的兩層cache(JVM+分布式cache,對開發(fā)人員透明,框架自動(dòng)具備這樣的能力 【這個(gè)以后的文章再表】),所以我們需要基于框架量身定做cache的集成。
? ? ? 說到這里,不得不由衷的佩服spring boot確實(shí)不錯(cuò),以前我還要基于spring cache 把guava cache和redis裝進(jìn)去,現(xiàn)在基于spring boot的 autoconfigure的cache封裝,就可以很方便把這些用起來,關(guān)于 springboot的cache使用,請參見:http://www.itdecent.cn/p/64f684bd0ce9? ? 但麻煩的地方在于,我們的框架+代碼自動(dòng)生成,在整個(gè)體系里,默認(rèn)的實(shí)現(xiàn)都在abstract抽象類,那么它只能做一次cacheNames的配置, 如果設(shè)置 cacheEvict(allEntries=true),會(huì)做全局的失效,而正常是這個(gè)模型內(nèi)的緩存失效,好在 可以自定義 CacheResolver。

????? 不過自定義的CacheResolver,需要注入cacheManager, 而cacheManager不能注入成功, 最終 使用 @Lazy,懶加載,并且 在spring boot應(yīng)用啟動(dòng)時(shí) 將ApplicationContext 設(shè)置給ApplicationContextHolder,在 需要的時(shí)候獲取到cachemanager設(shè)置給CacheResolver, 具體代碼:
@Component("runtimeImplCacheResolver")
@Lazy
public classRuntimeImplCacheResolverextendsAbstractCacheResolver {
privateApplicationContextctx;
publicRuntimeImplCacheResolver() {
//super.setCacheManager(SpringContextHolder.getApplicationContext().getBean(CacheManager.class));
}
@PostConstruct
public voidinit(){
super.setCacheManager(SpringContextHolder.getApplicationContext().getBean(CacheManager.class));
}
@Override
protectedCollection getCacheNames(CacheOperationInvocationContext context) {
if(context.getOperation().getCacheNames().contains("SECOMMONDYN")){
Set cacheName =newHashSet();
context.getTarget().getClass().toString();
String simpleName = context.getTarget().getClass().getSimpleName();
simpleName = simpleName.substring(0, simpleName.length() -11);
cacheName.add(simpleName);
returncacheName;
}else{
returncontext.getOperation().getCacheNames();
}
}
}
框架調(diào)用:
@CacheConfig(cacheNames ="SECOMMONDYN", cacheResolver ="runtimeImplCacheResolver")