在Spring中配置了Ehcache,由EhCacheManagerFactoryBean创建并且启用了一个CacheManager实例来管理Cache,那么CacheManager是怎么管理Cache的?Cache是由谁创建的?
org.springframework.cache. CacheManager:源码
public interface CacheManager {
@Nullable
Cache getCache(String var1);
Collection<String> getCacheNames();
}
我们可以看见在在Spring中创建的CacheManager只包含两个方法,没有任何创建cache实例的方法,那么cache是在哪里创建的?
net.sf.ehcache. CacheManager类用在了哪里?
简单的继承结构关系图:仅包含部分方法和类
(1) 从上面的继承结构图可知:Spring加载了EhCacheManager类由此获得了CacheManager接口的一个实例,可以通过Cache getCache(String var1)方法来获取Cache;
例如:
public class DemoTest {
private net.sf.ehcache.Cache customizedTTLCache;
@Autowired
public LoginServiceImpl(CacheManager customizedTTLCache) {
this.customizedTTLCache =
(net.sf.ehcache.Cache) ((EhCacheCache)
customizedTTLCache.getCache(CacheConstant.CUSTOMIZED_TTL)).getNativeCache();
}
(2) Cache getCache(String var1)方法的实现在AbstractCacheManager类中,而AbstractCacheManager实现了InitializingBean接口,在类初始化时会自动执行afterPropertiesSet()
public void afterPropertiesSet() {
this.initializeCaches();
}
public void initializeCaches() {
Collection<? extends Cache> caches = this.loadCaches();
ConcurrentMap var2 = this.cacheMap;
synchronized(this.cacheMap) {
this.cacheNames = Collections.emptySet();
this.cacheMap.clear();
Set<String> cacheNames = new LinkedHashSet(caches.size());
Iterator var4 = caches.iterator();
while(var4.hasNext()) {
Cache cache = (Cache)var4.next();
String name = cache.getName();
this.cacheMap.put(name, this.decorateCache(cache));
cacheNames.add(name);
}
this.cacheNames = Collections.unmodifiableSet(cacheNames);
}
}
protected abstract Collection<? extends Cache> loadCaches();
在initializeCaches()中用到了模板方法模式(设计模式)--loadCaches()方法的实现交给具体的子类,大致意思就是:这里需要得到Cache的集合,具体这个Cache集合从哪里来,具体的Cache的实现类是什么一概不管。
(3) EhCacheCacheManager实现了Collection<Cache> loadCaches()方法
在这里用到了net.sf.ehcache.CacheManager,那么Cache是在CacheManager类中创建的吗?
protected Collection<Cache> loadCaches() {
CacheManager cacheManager = this.getCacheManager();
Assert.state(cacheManager != null, "No CacheManager set");
Status status = cacheManager.getStatus();
if (!Status.STATUS_ALIVE.equals(status)) {
throw new IllegalStateException("An 'alive' EhCache CacheManager is required - current cache is " + status.toString());
} else {
String[] names = this.getCacheManager().getCacheNames();
Collection<Cache> caches = new LinkedHashSet(names.length);
String[] var5 = names;
int var6 = names.length;
for(int var7 = 0; var7 < var6; ++var7) {
String name = var5[var7];
caches.add(new EhCacheCache(this.getCacheManager().getEhcache(name)));
}
return caches;
}
}
loadCaches()方法中用到了CacheManager类中的两个方法 getCacheNames()和getEhcache(name),只是get了下cacheManager中已有的cache,那么那个已有的cache是怎么创建出来的?
(4) CacheManager类的 init(Configuration initialConfiguration, String configurationFileName, URL configurationURL, InputStream configurationInputStream)方法在bean加载的时候执行并初始化了所封装的属性,且调用了
doInit(Configuration configuration)方法 重点就是这里,在一层又一层的包裹下,终于找到了这里!!!
doInit()方法中创建并使用了ConfigurationHelper的实例:在这里我们终于看见了new Cache()的调用。
在ConfigurationHelper类中有多个创建Cache实例的方法,它们之间是互相调用的关系。
最终都是由 Ehcache createCache(CacheConfiguration cacheConfiguration)来创建;
(5) 在这里,ConfigurationHelper创建的net.sf.ehcache.Cache类型的实例,如何与Spring中org.springframework.cache.Cache匹配,看源码发现EhCacheCache实现了org.springframework.cache.Cache,并且关联了net.sf.ehcache.Cache,起到了适配器的作用,解决了类型转换的问题