2014-02-21 77 views
26

有沒有辦法在Spring 4或Spring Boot中初始化沒有xml的EhCache?在沒有XML的情況下在Spring 4中使用EhCache

我注意到Spring Boot 1.0.0.RC3沒有任何ehcache依賴關係,但Spring 4.0GA release post提到它改進了對EhCache的支持。此外,Spring 3擁有類org.springframework.cache.ehcache.EhCacheCacheManager,但這不再是依賴關係的一部分。

編輯: Spring 4確實有EhCache支持。您必須添加的依賴:

<groupId>org.springframework</groupId> 
<artifactId>spring-context-support</artifactId> 

EDIT2: 我試過下面,我想我很接近,但我得到了一個錯誤:

@Bean 
@Override 
public CacheManager cacheManager() { 
    CacheConfiguration cacheConfiguration = new CacheConfiguration(); 
    cacheConfiguration.setName("primary"); 
    cacheConfiguration.setMemoryStoreEvictionPolicy("LRU"); 
    cacheConfiguration.setMaxEntriesLocalHeap(0); 

    net.sf.ehcache.config.Configuration config = new net.sf.ehcache.config.Configuration(); 
    config.addCache(cacheConfiguration); 

    net.sf.ehcache.CacheManager cacheManager = new net.sf.ehcache.CacheManager(config); 
    cacheManager.setName("EhCache"); 

    return new EhCacheCacheManager(cacheManager); 
} 

@Bean 
public EhCacheManagerFactoryBean factoryBean() { 
    return new EhCacheManagerFactoryBean(); 
} 

錯誤

Caused by: 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: [Programmatically configured] 
    at net.sf.ehcache.CacheManager.assertNoCacheManagerExistsWithSameName(CacheManager.java:590) 
    at net.sf.ehcache.CacheManager.init(CacheManager.java:384) 
    at net.sf.ehcache.CacheManager.<init>(CacheManager.java:263) 
    at org.springframework.cache.ehcache.EhCacheManagerFactoryBean.afterPropertiesSet(EhCacheManagerFactoryBean.java:166) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1612) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1549) 
    ... 15 more 
+0

Spring4仍然有課,所以不知道你認爲它不再工作的想法。它在'spring-context-support'中。請參閱https://github.com/spring-projects/spring-framework/tree/master/spring-context-support/src/main/java/org/springframework/cache/ehcache。 –

回答

41

EhCache在Spring中的無XML配置

@Configuration 
@EnableCaching 
public class CachingConfig implements CachingConfigurer { 
    @Bean(destroyMethod="shutdown") 
    public net.sf.ehcache.CacheManager ehCacheManager() { 
     CacheConfiguration cacheConfiguration = new CacheConfiguration(); 
     cacheConfiguration.setName("myCacheName"); 
     cacheConfiguration.setMemoryStoreEvictionPolicy("LRU"); 
     cacheConfiguration.setMaxEntriesLocalHeap(1000); 

     net.sf.ehcache.config.Configuration config = new net.sf.ehcache.config.Configuration(); 
     config.addCache(cacheConfiguration); 

     return net.sf.ehcache.CacheManager.newInstance(config); 
    } 

    @Bean 
    @Override 
    public CacheManager cacheManager() { 
     return new EhCacheCacheManager(ehCacheManager()); 
    } 

    @Bean 
    @Override 
    public KeyGenerator keyGenerator() { 
     return new SimpleKeyGenerator(); 
    } 

    @Bean 
    @Override 
    public CacheResolver cacheResolver() { 
     return new SimpleCacheResolver(); 
    } 

    @Bean 
    @Override 
    public CacheErrorHandler errorHandler() { 
     return new SimpleCacheErrorHandler(); 
    } 
} 

或者您可以使用一個簡單的ConcurrentMapCache,在沒有XML的情況下運行,如下所示。

@Configuration 
@EnableCaching 
public class CachingConfig implements CachingConfigurer { 
    @Bean 
    @Override 
    public CacheManager cacheManager() { 
     SimpleCacheManager cacheManager = new SimpleCacheManager(); 

     List<Cache> caches = new ArrayList<Cache>(); 
     caches.add(new ConcurrentMapCache("myCacheName")); 
     cacheManager.setCaches(caches); 

     return cacheManager; 
    } 

    @Bean 
    @Override 
    public KeyGenerator keyGenerator() { 
     return new SimpleKeyGenerator(); 
    } 

    @Bean 
    @Override 
    public CacheResolver cacheResolver() { 
     return new SimpleCacheResolver(); 
    } 

    @Bean 
    @Override 
    public CacheErrorHandler errorHandler() { 
     return new SimpleCacheErrorHandler(); 
    } 
} 

編輯:更新對底層緩存增加的關機方法 編輯:增加了對錯誤處理程序和緩存解析器

+0

最初的java配置示例沒有顯示net.sf.ehcache.CacheManager也應該聲明爲一個bean,以便在bean銷燬時調用其shutdown()方法。 –

+0

如何在使用ConcurrentMapCache的「測試」和使用ehCache的生產級別之間切換?現在,我有一個application.properties和一個application-unittest.properties文件,用於在MYsql數據庫和內存數據庫之間切換以進行測試。你怎麼能用緩存做同樣的事情? –

+1

@KevinM你也可以使用Spring Profile。使用這將啓動一個或另一個基於活動配置文件。 http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/context/annotation/Profile.html – Erich

20

我做這兩個層次的抽象,每種技術的一個配置文件配置(Ehcache,Redis等)和一個通用配置文件。

下面是一個的Ehcache(Redis的是相似的):

@Configuration 
public class EhCacheConfiguration { 

    @Bean 
    public EhCacheCacheManager ehCacheCacheManager() { 

     return new EhCacheCacheManager(ehCacheManagerFactoryBean().getObject()); 
    } 


    @Bean 
    public EhCacheManagerFactoryBean ehCacheManagerFactoryBean() { 

     EhCacheManagerFactoryBean cacheManagerFactoryBean = new EhCacheManagerFactoryBean(); 

     cacheManagerFactoryBean.setConfigLocation(new ClassPathResource("ehcache.xml")); 
     cacheManagerFactoryBean.setShared(true); 

     return cacheManagerFactoryBean; 
    } 
} 

而這裏的一般一個(完整的Redis的鉤子):

@Configuration 
@EnableCaching 
public class CachingConfiguration implements CachingConfigurer { 

    @Qualifier("ehCacheCacheManager") 
    @Autowired(required = false) 
    private CacheManager ehCacheCacheManager; 

    @Qualifier("redisCacheManager") 
    @Autowired(required = false) 
    private CacheManager redisCacheManager; 


    @Bean 
    @Override 
    public CacheManager cacheManager() { 

     List<CacheManager> cacheManagers = Lists.newArrayList(); 

     if (this.ehCacheCacheManager != null) { 
      cacheManagers.add(this.ehCacheCacheManager); 
     } 

     if (this.redisCacheManager != null) { 
      cacheManagers.add(this.redisCacheManager); 
     } 

     CompositeCacheManager cacheManager = new CompositeCacheManager(); 

     cacheManager.setCacheManagers(cacheManagers); 
     cacheManager.setFallbackToNoOpCache(false); 

     return cacheManager; 
    } 


    @Bean 
    @Override 
    public KeyGenerator keyGenerator() { 

     return new DefaultKeyGenerator(); 
    } 
} 
+0

+1喜歡抽象的想法。將與此 – Erich

+0

玩我需要它來結合兩個緩存管理器;它可能是你的需要矯枉過正,但刪除組合應該是直截了當的。 –

相關問題