2014-02-21 2 views
26

Есть ли способ инициализировать EhCache без xml в Spring 4 или Spring Spring?Использование EhCache весной 4 без XML

Я заметил Spring Boot 1.0.0.RC3 не имеет никаких зависимостей ehcache, но Spring 4.0GA release post упомянул, что у него улучшенная поддержка EhCache. Кроме того, Spring 3 имел класс org.springframework.cache.ehcache.EhCacheCacheManager, но это уже не часть зависимостей.

Редактировать: Весна 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 без 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(); 
    } 
} 

Edit: обновление, чтобы добавить метод отключения в основной кэш Edit: Добавлена ​​конфигурация для обработки ошибок и кэш распознавателя

+0

Исходный пример конфигурации Java не показал, что net.sf.ehcache.CacheManager также должен быть объявлен как bean-компонент, так что его метод shutdown() вызывается, когда бит уничтожается. –

+0

Как вы можете переключаться между «тестовым» с помощью ConcurrentMapCache и уровнем производительности с использованием ehCache? Прямо сейчас у меня есть application.properties и файлы application-unittest.properties, которые я использую для переключения между двоичными файлами MYsql и db для тестирования. Как вы можете сделать то же самое с кешем? –

+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

Мне нужно было это, чтобы объединить двух менеджеров кэша; это может быть излишним для ваших нужд, но удаление композита должно быть простым. –

Смежные вопросы