1. 程式人生 > >springboot+shiro+ehcache整合之Another unnamed CacheManager already exists in the same VM.

springboot+shiro+ehcache整合之Another unnamed CacheManager already exists in the same VM.

ehcache.xml配置檔案

<?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"
         name="myEhcache">
    <diskStore path="java.io.tmpdir/Tmp_EhCache"/>
<defaultCache eternal="false" maxElementsInMemory="1000" overflowToDisk="false" diskPersistent="false" timeToIdleSeconds="0" timeToLiveSeconds="600" memoryStoreEvictionPolicy="LRU"/> <cache
name="user" eternal="false" maxElementsInMemory="10000" overflowToDisk="false" diskPersistent="false" timeToIdleSeconds="0" timeToLiveSeconds="0" memoryStoreEvictionPolicy="LFU"/>
<!-- 快取配置 name: 快取名稱。 maxElementsInMemory: 快取最大個數。 eternal: 物件是否永久有效,一但設定了,timeout將不起作用。 timeToIdleSeconds: 設定物件在失效前的允許閒置時間(單位:秒)。僅當eternal=false物件不是永久有效時使用,可選屬性,預設值是0,也就是可閒置時間無窮大。 timeToLiveSeconds: 設定物件在失效前允許存活時間(單位:秒)。最大時間介於建立時間和失效時間之間。僅當eternal=false物件不是永久有效時使用,預設是0.,也就是物件存活時間無窮大。 overflowToDisk: 當記憶體中物件數量達到maxElementsInMemory時,Ehcache將會物件寫到磁碟中。 diskSpoolBufferSizeMB: 這個引數設定DiskStore(磁碟快取)的快取區大小。預設是30MB。每個Cache都應該有自己的一個緩衝區。 maxElementsOnDisk: 硬碟最大快取個數。 diskPersistent: 是否快取虛擬機器重啟期資料 Whether the disk store persists between restarts of the Virtual Machine. The default value is false. diskExpiryThreadIntervalSeconds:磁碟失效執行緒執行時間間隔,預設是120秒。 memoryStoreEvictionPolicy: 當達到maxElementsInMemory限制時,Ehcache將會根據指定的策略去清理記憶體。預設策略是LRU(最近最少使用)。你可以設定為FIFO(先進先出)或是LFU(較少使用)。 clearOnFlush: 記憶體數量最大時是否清除。 -->
</ehcache>

注意:
1、原因是:如果使用的ehcache版本超過了2.5.0,那麼<ehcache name="myEhcache">就很重要,不然ehcache會自動載入為預設的名字_default_,而ehcache2.5以後只允許建立單例的CacheManager,從而報重複載入CacheManager的錯誤。

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'cacheManager' defined in class path resource [org/springframework/boot/autoconfigure/cache/EhCacheCacheConfiguration.class]: Unsatisfied dependency expressed through method 'cacheManager' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'ehCacheCacheManager' defined in class path resource [org/springframework/boot/autoconfigure/cache/EhCacheCacheConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [net.sf.ehcache.CacheManager]: Factory method 'ehCacheCacheManager' threw exception; nested exception is net.sf.ehcache.CacheException: Another unnamed CacheManager already exists in the same VM. Please provide unique names for each CacheManager in the config or do one of following:
1. Use one of the CacheManager.create() static factory methods to reuse same CacheManager with same name or create one if necessary
2. Shutdown the earlier cacheManager before creating new one with same name.
The source of the existing CacheManager is: InputStreamConfigurationSource [[email protected]5f61d894]

2、解決方法
第一種:jar降級

<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core</artifactId>
 <version>2.4.8</version>
</dependency> 
不過,如果是採用springboot的pom.xml統一版本號管理就有可能改了ehcache還是沒有什麼作用,這時可以採用第二種

第二種:建立ehCacheManager的時候,先判斷是否有cacheManager,沒有的情況下再進行建立,判斷的關鍵就是我們一開始在編寫ehcache.xml的時候強調的name屬性,通過該屬性來判斷cacheManager是否載入了。

@Bean
    public EhCacheManager ehCacheManager() {
        //注意myEhcache對應上面的<ehcache name="myEhcache">
        CacheManager cacheManager = CacheManager.getCacheManager("myEhcache");
        if(cacheManager == null){
            cacheManager = CacheManager.create();
        }
        EhCacheManager ehCacheManager = new EhCacheManager();
        ehCacheManager.setCacheManager(cacheManager);
        return ehCacheManager;
    }