Using EhCache in Spring 4 without XML
I do this at two levels of abstraction, a configuration file per technology (Ehcache, Redis, etc.) and a general configuration file.
Here's the one for Ehcache (Redis would be similar):
@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;
}
}
And here's the general one (complete with Redis hooks):
@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();
}
}
XML-less configuration of EhCache in Spring
@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();
}
}
Alternatively for testing, you can use a simple ConcurrentMapCache running without XML as below.
@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: Updated to add shutdown method on underlying cache
Edit: Added configuration for error handler and cache resolver
Edit: changing constructor call on SimpleCacheResolver
which resolves CacheManager must not be null
issue (Spring v5.1+)
@Configuration
@EnableCaching
public class CachingConfig implements CachingConfigurer {
public static final String USER_CACHE_INSTANCE = "my-spring-ehcache";
private final CacheManager cacheManager;
private final net.sf.ehcache.CacheManager ehCacheManager;
public CachingConfig() {
CacheConfiguration cacheConfiguration = new CacheConfiguration();
cacheConfiguration.setName(USER_CACHE_INSTANCE);
cacheConfiguration.setMemoryStoreEvictionPolicy("LRU");
cacheConfiguration.setMaxEntriesLocalHeap(1000);
net.sf.ehcache.config.Configuration config
= new net.sf.ehcache.config.Configuration();
config.addCache(cacheConfiguration);
this.ehCacheManager = net.sf.ehcache.CacheManager.newInstance(config);
this.cacheManager = new EhCacheCacheManager(ehCacheManager);
}
@Bean(destroyMethod="shutdown")
public net.sf.ehcache.CacheManager ehCacheManager() {
return ehCacheManager;
}
@Bean
@Override
public CacheManager cacheManager() {
return cacheManager;
}
@Bean
@Override
public KeyGenerator keyGenerator() {
return new SimpleKeyGenerator();
}
@Bean
@Override
public CacheResolver cacheResolver() {
return new SimpleCacheResolver(cacheManager);
}
@Bean
@Override
public CacheErrorHandler errorHandler() {
return new SimpleCacheErrorHandler();
}
}