spring4.3 ehcache 2.10.+ 配置多個緩存

spring 如何整合ehcache,以及ehcache 如何整合mybatis 這裏不作詳細介紹。java

簡單說一下需求:我有不一樣的的模塊須要配置緩存,不一樣的模塊有須要不同的緩存策略,那麼就能夠爲chcache 配置多個的緩存,根據不一樣的名稱去訪問。spring

1.先看 ehcache.xml(放在src目錄下)緩存

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd" updateCheck="false">
	<diskStore path="java.io.tmpdir" />
	
	<cache name="localtest"  
        eternal="false" maxElementsInMemory="1000" 
		overflowToDisk="false" 
		diskPersistent="false" 
		timeToIdleSeconds="0"
		timeToLiveSeconds="600" 
		memoryStoreEvictionPolicy="LRU" />
	
	
	<!--配置token 緩存策略  -->
	<cache name="test1" 
		eternal="false" 
		maxElementsInMemory="20000"
		overflowToDisk="false" 
		diskPersistent="false"
		timeToIdleSeconds="0"
		timeToLiveSeconds="6000" 
		memoryStoreEvictionPolicy="LRU" />
		
		<!--配置token 緩存策略  -->
	<cache name="test2" 
		eternal="false" 
		maxElementsInMemory="12350"
		overflowToDisk="false" 
		diskPersistent="false"
		timeToIdleSeconds="300"
		timeToLiveSeconds="3000" 
		memoryStoreEvictionPolicy="LRU" />
			
</ehcache>

能夠看到這裏配置了三個cache : localtest test1 test2   (具體參數配置請參考官方文檔)mybatis

2。再看 applicationContext.xml 中的配置:app

<!-- 配置Ehcache緩存管理器,讀取配置文件 -->
    <bean id="ehCacheManagerFactoryBean" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
        <property name="cacheManagerName" value="testManager"></property>
        <property name="configLocation" value="classpath:ehcache.xml"></property>
        <property name="shared" value="true"></property>
    </bean>
    
    <!-- 配置緩存管理器,獲取cache -->
     <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager" >
        <property name="cacheManager" ref="ehCacheManagerFactoryBean" />
    </bean>

3. 在代碼中使用ide

@Resource
	EhCacheCacheManager cacheManager;

//存
org.springframework.cache.Cache cache = cacheManager.getCache("test1");
cache.put(key, value);

//取
if (StringUtils.isNotBlank(key)) {
     Cache cache = cacheManager.getCache("test1");		  		   
	 String value= cache.get(key,String.class);			   
}

最後 說說爲何我是這樣配置的以及開發中遇到的問題:this

     一開始配置文件並無放置在 src 目錄下面,同時也沒有爲ehCacheManagerFactoryBean 配置cachemanagerName,這樣的一旦 share 配置爲 false  啓動便會抱錯,url

Another unnamed CacheManager already exists in the same VM. Please provide unique names for each CacheManager in the config or do one of followingspa

已經存在一個cacheManager ,如何不讓共享那麼必須配置一個新的惟一的名字,因此share 設置爲true ,同時爲其配置了一個名字(若是不想設置爲true 那麼能夠添加 命名)。debug

可是這樣配置之後,debug 發現:並不能從cacheManaer 中獲取到指定名稱的cache!

在修改N次配置後,我忽然想也許我配置的ehcache.xml根本沒有生效!

繼續debug > 發如今啓動的時候

EhCacheManagerFactoryBean中有個方法:afterPropertiesSet() 

EhCacheManagerUtils.parseConfiguration(this.configLocation) : ConfigurationFactory.parseConfiguration());

public static Configuration parseConfiguration() throws CacheException {
        ClassLoader standardClassloader = Thread.currentThread().getContextClassLoader();
        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);

        }
        Configuration configuration = parseConfiguration(url);
        configuration.setSource(ConfigurationSource.getConfigurationSource());
        return configuration;
    }

這個方法會加載 ehcache的配置文件,奇怪的是並無找我配置ehcache.xml,因此自動調用了默認的配置,可是尚未完,斷點第二次跑到這裏的時候才加載我配置的xml ! 經過名字會發現兩次的cacheManagerName 是不同的。這樣就解釋了爲何經過cacheManger 獲取不到的指定的cache了! 由於此時的cacheManager 就是默認的那個而非加載個人xml的那個(真特麼拗口!)(若是能到拿到那個cachemanger 天然就能夠獲取咱們定義的cache了)

既然默認的非要去src下找配置,那就如其所願好了! 果斷把配置傳送過去。

而後經過 遍歷全部的cache 就能夠看到咱們的定義的test1 test2 localtest了      

Collection<String> cacheNames = cacheManager.getCacheNames();
        for (String string : cacheNames) {
            System.out.println("names:"+string);
       }

此外:若是配置mybatis + ehcache能夠看到cache中同時存在mybatis 的緩存 key 天然是namespace了。

走到這裏,我又試了一下,將前面提到的 share 設置爲false,經過cacheManager.getName() 獲取其名字,獲得的就是配置裏的 testManager! 而且這個Manager 中不存在mybatis 的cache 由於mybatis  的cache 自_defaut_ 那個 cacheManger 中!!! 

固然到這裏只是解決了暫時的問題,更多的內容還有待研究。若是有問題但願你們不吝賜教!

相關文章
相關標籤/搜索