I configured spring method caching with ehcache and annotation driven configuration.
I would like however to be able to disable it from a configuration file we use in the application.
My first idea was to call net.sf.ehcache.CacheManager.CacheManager()
with no arguments if method caching is disabled. This throws exception:
java.lang.IllegalArgumentException: loadCaches must not return an empty Collection
at org.springframework.util.Assert.notEmpty(Assert.java:268)
at org.springframework.cache.support.AbstractCacheManager.afterPropertiesSet(AbstractCacheManager.java:49)
My second idea was to configure the net.sf.ehcache.CacheManager.CacheManager()
with default data so that the cache is not used (maxElementsInMemory 0 etc.). But then the cache is still used, which is not what I want.
There is a property net.sf.ehcache.disabled
but I do not want do disable hibernate caching that also uses ehcache.
Q
How can I configure everything to have spring method caching but disable it from my external configuration file? I do not want to modify the application-context nor the code to enable/disable method caching. Only the configuration file we use in the application can be modified.
Spring provides two ways to evict a cache, either by using the @CacheEvict annotation on a method, or by auto-wiring the CacheManger and clearing it by calling the clear() method.
This allows for customizing the strategy for cache key generation, per Spring's KeyGenerator SPI. Normally, @EnableCaching will configure Spring's SimpleKeyGenerator for this purpose, but when implementing CachingConfigurer , a key generator must be provided explicitly.
The @EnableCaching annotation triggers a post-processor that inspects every Spring bean for the presence of caching annotations on public methods. If such an annotation is found, a proxy is automatically created to intercept the method call and handle the caching behavior accordingly.
What I was looking for was NoOpCacheManager
:
To make it work I switched from xml bean creation to a factory
I did something as follows:
@Bean
public CacheManager cacheManager() {
final CacheManager cacheManager;
if (this.methodCacheManager != null) {
final EhCacheCacheManager ehCacheCacheManager = new EhCacheCacheManager();
ehCacheCacheManager.setCacheManager(this.methodCacheManager);
cacheManager = ehCacheCacheManager;
} else {
cacheManager = new NoOpCacheManager();
}
return cacheManager;
}
You can use a spring profile, to enable (or not) the spring caching support
<beans profile="withCache">
<cache:annotation-driven />
</beans>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With