Custom CacheResolver not working

I have a Spring boot project with a custom CacheResolver , since I need to determine the runtime that I want to use the cache for, I have no compilation errors, but when I do some tests and CacheResolver gap on my custom CacheResolver it never enters into it .

This is my cache class configuration:

 @Configuration @EnableCaching(proxyTargetClass = true) @PropertySource(CacheConfig.CLASSPATH_DEPLOY_CACHE_PROPERTIES_PROPERTIES) public class CacheConfig extends CachingConfigurerSupport{ public static final String CLASSPATH_DEPLOY_CACHE_PROPERTIES_PROPERTIES = "classpath:/deploy/cache-properties.properties"; public static final String CACHEABLE_DOCUMENTS_PROPERTY = "cacheable.documents"; public static final String TTL_CACHEABLE_DOCUMENTS_PROPERTY = "ttl.cacheable.documents"; public static final String SIZED_CACHEABLE_DOCUMENTS_PROPERTY = "sized.cacheable.documents"; public static final String CACHE_NAME = "permanentCache"; public static final String TTL_CACHE = "ttlCache"; public static final String SIZED_CACHE = "sizedCache"; public static final String CACHEABLE_DOCUMENTS = "cacheableDocuments"; public static final String SIZED_CACHEABLE_DOCUMENTS = "sizedCacheableDocuments"; public static final int WEIGHT = 1000000; public static final int TO_KBYTES = 1000; @Inject protected Environment environment; //@Bean @Override public CacheManager cacheManager() { SimpleCacheManager cacheManager = new SimpleCacheManager(); GuavaCache sizedCache = new GuavaCache(SIZED_CACHE, CacheBuilder.newBuilder().maximumWeight(WEIGHT).weigher( (key, storable) -> { String json = ((Storable) storable).toJson(); return json.getBytes().length / TO_KBYTES; } ).build()); GuavaCache permanentCache = new GuavaCache(CACHE_NAME,CacheBuilder.newBuilder().build()); //GuavaCache ttlCache = new GuavaCache(TTL_CACHE, CacheBuilder.newBuilder().expireAfterWrite(30, TimeUnit.MINUTES).build()); cacheManager.setCaches(Arrays.asList(permanentCache,sizedCache)); return cacheManager; } @Bean(name = "wgstCacheResolver") @Override public CacheResolver cacheResolver(){ CacheResolver cacheResolver = new WgstCacheResolver(cacheManager(),cacheableDocuments(),sizedCacheableDocuments()); return cacheResolver; } @Bean(name = CACHEABLE_DOCUMENTS) public List<String> cacheableDocuments(){ String[] cacheableDocuments = StringUtils.commaDelimitedListToStringArray(environment.getProperty(CACHEABLE_DOCUMENTS_PROPERTY)); return Arrays.asList(cacheableDocuments); } @Bean(name = SIZED_CACHEABLE_DOCUMENTS) public List<String> sizedCacheableDocuments(){ String[] sizedCacheableDocuments = StringUtils.commaDelimitedListToStringArray(environment.getProperty(SIZED_CACHEABLE_DOCUMENTS_PROPERTY)); return Arrays.asList(sizedCacheableDocuments); } } 

Here is my CacheResolver

 public class WgstCacheResolver extends AbstractCacheResolver { private final List<String> cacheableDocuments; private final List<String> sizedCacheableDocuments; public WgstCacheResolver(final CacheManager cacheManager,final List<String> cacheableDocuments, final List<String> sizedCacheableDocuments) { super(cacheManager); this.cacheableDocuments = cacheableDocuments; this.sizedCacheableDocuments = sizedCacheableDocuments; } /** * Resolves the cache(s) to be updated on runtime * @param context * @return*/ @Override protected Collection<String> getCacheNames(final CacheOperationInvocationContext<?> context) { final Collection<String> cacheNames = new ArrayList<>(); final AbstractDao dao = (AbstractDao)context.getTarget(); final String documentType = dao.getDocumentType().toString(); if (cacheableDocuments.contains(documentType)){ cacheNames.add("permanentCache"); } if (sizedCacheableDocuments.contains(documentType)){ cacheNames.add("sizedCache"); } return cacheNames; } } 

And here is my DAO, where I use the cache:

  @Component @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE, proxyMode = ScopedProxyMode.DEFAULT) @CacheConfig(cacheResolver = "wgstCacheResolver") public class CacheableDao<T extends Storable> extends AbstractDao<T> { private final Logger logger = LoggerFactory.getLogger(CacheableDao.class); public CacheableDao(final Bucket bucket, final Class<T> typeParameterClass, final DocumentType documentType) { super(bucket, typeParameterClass, documentType); } @Cacheable(key = "{#root.methodName, #root.target.generateFullKey(#key)}") public T get(final String key) throws DatastoreAccessException, ObjectMappingException { //do something } . . . } 

I tried to implement CacheResolver instead of the AbstractCacheResolver extension, but that didn't make any difference.

Thanks.

+5
source share
2 answers

Cache names should be included at some point, just specifying CacheResolver for use is not enough, the @Cacheable class should know about the available cache names, so I included them with the @CacheConfig annotation

 @CacheConfig(cacheNames = {WgstCacheConfig.PERMANENT_CACHE, WgstCacheConfig.SIZED_CACHE}, cacheResolver = WgstCacheConfig.WGST_CACHE_RESOLVER) public class CacheableDao<T extends Storable> extends AbstractDao<T> { 

One thing that I don't like is that I need to provide a null CacheManager , even if I don't use it, otherwise I get the following error:

 Caused by: java.lang.IllegalStateException: No CacheResolver specified, and no bean of type CacheManager found. Register a CacheManager bean or remove the @EnableCaching annotation from your configuration. 

So, I left it like this and it works:

  @Bean public CacheManager cacheManager() { return null; } @Bean(name = WGST_CACHE_RESOLVER) public CacheResolver cacheResolver(){ CacheResolver cacheResolver = new WgstCacheResolver(cacheableDocuments(),sizedCacheableDocuments(),getPermanentCache(), getSizedCache()); return cacheResolver; } 

Repeat my tests passing my custom CacheResolver and it behaves as expected to allow the correct cache (s)

My configuration class no longer extends CachingConfigurerSupport .

+1
source

After a little back and forth (sorry for that!) It turns out that this is really a bug in the Spring Framework.

I created SPR-13081 . Expect corrections for the next service release ( 4.1.7.RELEASE ). Thanks for the sample project!

-1
source

All Articles