2013-01-24 20:11:33.0|分类: struts源码分析|浏览量: 1701
上文把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中 |