2013-01-24 20:11:33.0|分类: struts源码分析|浏览量: 2050
|
上文把encache的基本代码展示了,但是有个疑问:没有设置缓存文件ehcache.xml,他是怎么设置进去的啊?并且读到里面的数据呢? 下面详细解释: 1、TestEnCache中mian函数中,获得缓存数据
String cacheName="cacheA"; String key="key"; String value="oschina"; //set(cacheName, key, value); String gValue = (String)CacheManager.get(cacheName, key);//A 2、CacheManager中get(String name, Serializable key)代码:
/**
* 获取缓存中的数据
* @param name 缓存名
* @param key
* @return
*/
public final static Object get(String name, Serializable key){
if(name!=null && key != null)
return _getCache(name).get(key);
return null;
} 注释:首先判断name和key是否为空,如果不为空,获得name相应的缓存,并且从缓存中获取key对应的值
3、先看看_getCache(String cache_name)的源码:
private static CacheProvider provider; private final static Cache _getCache(String cache_name) {
if(provider == null){
provider = new EhCacheProvider();
provider.start();
}
return provider.buildCache(cache_name);
}
注释:CacheManager中定义了一个静态变量provider,首先判断provider是否为null,如果为空就new EhCacheProvider ,并且调用start()方法。 3.1有必要先看看start()方法: public void start() throws CacheException {
if (manager != null) {
log.warn("Attempt to restart an already started EhCacheProvider. Use sessionFactory.close() " +
" between repeated calls to buildSessionFactory. Using previously created EhCacheProvider." +
" If this behaviour is required, consider using net.sf.ehcache.hibernate.SingletonEhCacheProvider.");
return;
}
manager = new CacheManager();
_cacheManager = new Hashtable<String, EhCache>();
} 注释:manager是net.sf.ehcache.CacheManager类型
_cacheManager是Hashtable<String, EhCache>()类型,key是缓存的name,value是EhCache对象。 4、再回到_getCache(String cache_name)中最后一行buildCache(String name)代码: public EhCache buildCache(String name) throws CacheException {
EhCache ehcache = _cacheManager.get(name);
if(ehcache != null)
return ehcache ;
try {
net.sf.ehcache.Cache cache = manager.getCache(name);
if (cache == null) {
log.warn("Could not find configuration [" + name + "]; using defaults.");
manager.addCache(name);
cache = manager.getCache(name);
log.debug("started EHCache region: " + name);
}
synchronized(_cacheManager){
ehcache = new EhCache(cache);
_cacheManager.put(name, ehcache);
return ehcache ;
}
}
catch (net.sf.ehcache.CacheException e) {
throw new CacheException(e);
}
} 注释:(1)首先会查看_cacheManager中是是否保存了和name相对应的EhCache,如果不为空,直接返回
(2)manager.getCache(name)获得net.sf.ehcache.Cache对象,manager.getCache(name)源码: protected final Map caches = new ConcurrentHashMap(); public Cache getCache(String name) throws IllegalStateException, ClassCastException {
checkStatus();
return (Cache) caches.get(name);
} 这里也是在map中获取和name相对应的Cache,但是没有看到添加啊?怎么搞进来的值呢?后面马上会说到。
(3)new EhCache(cache)创建ehcache对象 (4)把ehcache保存到_cacheManager里面 5、上面中manager.getCache(name)获得net.sf.ehcache.Cache对象不是null,这是为什么呢?到现在为止没有看到添加map中值啊?在前面执行new CacheManager(),恩,看看CacheManager构造函数吧。 public CacheManager() throws CacheException {
//default config will be done
status = Status.STATUS_UNINITIALISED;
init(null, null, null, null);
}
/**
* initialises the CacheManager
*/
protected void init(Configuration configuration, String configurationFileName, URL configurationURL,
InputStream configurationInputStream) {
Configuration localConfiguration = configuration;
if (configuration == null) {
localConfiguration = parseConfiguration(configurationFileName, configurationURL, configurationInputStream);
} else {
localConfiguration.setSource("Programmatically configured.");
}
if (localConfiguration.getName() != null) {
this.name = localConfiguration.getName();
}
this.terracottaConfigConfiguration = localConfiguration.getTerracottaConfiguration();
Map<String, CacheConfiguration> cacheConfigs = localConfiguration.getCacheConfigurations();
for (CacheConfiguration config : cacheConfigs.values()) {
if (config.isTerracottaClustered()) {
terracottaStoreFactory = TerracottaStoreHelper.newStoreFactory(
cacheConfigs, localConfiguration
.getTerracottaConfiguration());
break;
}
}
/*
* May not have any CacheConfigurations yet, so check the default configuration.
*/
if (terracottaStoreFactory == null) {
if (localConfiguration.getDefaultCacheConfiguration().isTerracottaClustered()) {
terracottaStoreFactory = TerracottaStoreHelper.newStoreFactory(cacheConfigs, localConfiguration
.getTerracottaConfiguration());
}
}
ConfigurationHelper configurationHelper = new ConfigurationHelper(this, localConfiguration);
configure(configurationHelper);
status = Status.STATUS_ALIVE;
for (CacheManagerPeerProvider cacheManagerPeerProvider : cacheManagerPeerProviders.values()) {
cacheManagerPeerProvider.init();
}
cacheManagerEventListenerRegistry.init();
addShutdownHookIfRequired();
cacheManagerTimer = new FailSafeTimer(getName());
checkForUpdateIfNeeded(localConfiguration.getUpdateCheck());
terracottaStoreFactoryCreated.set(terracottaStoreFactory != null);
//do this last
addConfiguredCaches(configurationHelper);
initializeMBeanRegistrationProvider(localConfiguration);
} 注释:(1)构造函数中知识简单的调用了一下init(null, null, null, null)方法
(2)configuration传值为空,会执行代码localConfiguration = parseConfiguration(configurationFileName, configurationURL, configurationInputStream),看看代码: private synchronized Configuration parseConfiguration(String configurationFileName, URL configurationURL,
InputStream configurationInputStream) throws CacheException {
reinitialisationCheck();
Configuration configuration;
String configurationSource;
if (configurationFileName != null) {
LOG.debug("Configuring CacheManager from {}", configurationFileName);
configuration = ConfigurationFactory.parseConfiguration(new File(configurationFileName));
configurationSource = "file located at " + configurationFileName;
} else if (configurationURL != null) {
configuration = ConfigurationFactory.parseConfiguration(configurationURL);
configurationSource = "URL of " + configurationURL;
} else if (configurationInputStream != null) {
configuration = ConfigurationFactory.parseConfiguration(configurationInputStream);
configurationSource = "InputStream " + configurationInputStream;
} else {
LOG.debug("Configuring ehcache from classpath.");
configuration = ConfigurationFactory.parseConfiguration();
configurationSource = "classpath";
}
configuration.setSource(configurationSource);
return configuration;
} configurationFileName,configurationURL,configurationInputStream全部传值为空,所以会执行代码: configuration = ConfigurationFactory.parseConfiguration(),没办法看看他到底干嘛了吧:
public static Configuration parseConfiguration() throws CacheException {
ClassLoader standardClassloader = ClassLoaderUtil.getStandardClassLoader();
URL url = null;
if (standardClassloader != null) {
url = standardClassloader.getResource(DEFAULT_CLASSPATH_CONFIGURATION_FILE);
}
if (url == null) {
url = ConfigurationFactory.class.getResource(DEFAULT_CLASSPATH_CONFIGURATION_FILE);
}
if (url != null) {
LOG.debug("Configuring ehcache from ehcache.xml found in the classpath: " + url);
} else {
url = ConfigurationFactory.class.getResource(FAILSAFE_CLASSPATH_CONFIGURATION_FILE);
LOG.warn("No configuration found. Configuring ehcache from ehcache-failsafe.xml "
+ " found in the classpath: {}", url);
}
return parseConfiguration(url);
}
DEFAULT_CLASSPATH_CONFIGURATION_FILE是/ehcache.xml,这里主要的任务就是加载
ehcache.xml文件,哈哈哈,这就是加载
ehcache.xml文件了。
回到init方法中,然后会把文件中数据添加到configurationHelper,然后addConfiguredCaches(configurationHelper)会把里面的缓存添加到ehcaches中, private void addConfiguredCaches(ConfigurationHelper configurationHelper) {
Set unitialisedCaches = configurationHelper.createCaches();
for (Iterator iterator = unitialisedCaches.iterator(); iterator.hasNext();) {
Ehcache unitialisedCache = (Ehcache) iterator.next();
addCacheNoCheck(unitialisedCache);
}
}
private void addCacheNoCheck(Ehcache cache) throws IllegalStateException,
ObjectExistsException, CacheException {
if (ehcaches.get(cache.getName()) != null) {
throw new ObjectExistsException("Cache " + cache.getName() + " already exists");
}
cache.setCacheManager(this);
cache.setDiskStorePath(diskStorePath);
cache.initialise();
try {
cache.bootstrap();
} catch (CacheException e) {
LOG.warn("Cache " + cache.getName() + "requested bootstrap but a CacheException occured. " + e.getMessage(), e);
}
ehcaches.put(cache.getName(), cache);
if (cache instanceof Cache) {
caches.put(cache.getName(), cache);
}
//Don't notify initial config. The init method of each listener should take care of this.
if (status.equals(Status.STATUS_ALIVE)) {
cacheManagerEventListenerRegistry.notifyCacheAdded(cache.getName());
}
}
恩,到这里就结束了。
这篇文章的重点: (1)在哪加载ehcache.xml文件 (2)在哪把缓存相应的信息添加到ehcaches中 |
