Reputation: 81
Imagine you creating a Spring library which provides a service component for some remote service. The service component wants to cache response data internally, for which Spring caching is a very good fit. Also imagine the cache needs to be slightly more advanced than any of the default ones (timeouts, maximum sizes, etc), so the library provides a cache manager to create it. However, you don't want the third-party cache manager to suddenly be responsible for all caching used in the project where the library is included (the project might have it's own caches).
The behaviour I am observing is that if the project is using caching configured using a simple application.properties (with let's say ehcache - see example below), the cache manager provided by the component gets called to create all caches, no matter how I structure the code. Is this happening because the project haven't provided any cache manager of it's own?
Is it not possible to have caching like this in a library-provided service without the project being involved? It's very important for the use-case that the library can provide the cache without interfering with project caching.
@Configuration
public class SpringAceClientCacheConfiguration
{
@Bean
public CacheManager serviceCacheManager()
{
return new GuavaCacheManager("service-data") {
@Override
public Cache getCache(String name) {
Logger.getLogger(getClass().getName()).info("Creating new cache for " + name + "...");
return new GuavaCache(name, CacheBuilder.newBuilder().build());
}
};
}
}
spring.cache.jcache.config=ehcache3.xml
<config xmlns='http://www.ehcache.org/v3'
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jsr107="http://www.ehcache.org/v3/jsr107"
xsi:schemaLocation="http://www.ehcache.org/v3 http://www.ehcache.org/schema/ehcache-core-3.0.xsd
http://www.ehcache.org/v3/jsr107 http://www.ehcache.org/schema/ehcache-107-ext-3.0.xsd">
<cache alias="content">
<heap unit="entries">4096</heap>
<jsr107:mbeans enable-statistics="true"/>
</cache>
</config>
I see the logging call for both the 'service-data' and the 'content' caches. The service cache configuration only cares about it's own service data cache. Should I not be able to provide a cache manager just for this cache without the project having to declare a separate one with @Primary (which I believe might work, but I haven't tried it yet)?
Thanks for any help!
Upvotes: 2
Views: 1557
Reputation: 33121
There is no immediate notion of "qualified" CacheManager
so when you use the annotation model, you are expected to provide one CacheManager
bean that is managing your complete cache infrastructure.
However, the cache abstraction has a CacheResolver
SPI. So, your third party lib could require one:
@Cacheable(cacheResolver = "requiredCacheResolver")
public Foo someMethod(String id)
Then the requiredCacheResolver
bean can get the cache information from whatever CacheManager
you like. The third party lib could provide an implementation that takes a CacheManager
or individual caches as a parameter.
I am not sure that I would recommend that, however. If you are using caching with a third party library, you should define in your documentation the caches that you require (name and semantic so that expiration can be configured accordingly). Then, each user of your library should configure those caches in their infrastructure. In the end, you'll have to do that anyway and hiding that from the user does not seem a good idea.
Upvotes: 3