spring cache with custom cacheResolver

▼魔方 西西 提交于 2020-01-02 23:15:08

问题


I wand to have dynamic cache names, and spring 4.1 allows that

Since Spring 4.1, the value attribute of the cache annotations are no longer mandatory since this particular information can be provided by the CacheResolver regardless of the content of the annotation.

Notice how I paranoidly set cacheResolver on all possible levels:

@Cacheable(cacheResolver = "defaultCacheResolver")
@CacheConfig(cacheResolver = "defaultCacheResolver")
public interface GatewayRepository extends CrudRepository<Gateway, Integer> {
    @Cacheable(cacheResolver = "defaultCacheResolver")
    Gateway findByBulkId(int bulkId);
}

Spring 4.1.5 still fails to validate the config with error: Caused by: java.lang.IllegalStateException: No cache names could be detected on 'public abstract skunkworks.data.Gateway skunkworks.repos.GatewayRepository.findByBulkId(int)'. Make sure to set the value parameter on the annotation or declare a @CacheConfig at the class-level with the default cache name(s) to use. at org.springframework.cache.annotation.SpringCacheAnnotationParser.validateCacheOperation(SpringCacheAnnotationParser.java:240)


回答1:


I think you should specify cache name somewhere in your code.

In the basic usage, cache name is given in @Cacheable, @CachePut or @CacheEvict annotations.

@Cacheable(cacheNames = "myCache")

You can also specify it in the @CacheConfig which is a class-level annotation.

@CacheConfig(cacheNames = "myCache")

If you need more flexible caching mechanism, you can use CacheResolver. In this case you should create your own CacheResolver. Something along these lines:

public class CustomCacheResolver implements CacheResolver {

    private final CacheManager cacheManager;

    public CustomCacheResolver(CacheManager cacheManager){
        this.cacheManager = cacheManager;
    }

    @Override
    public Collection<? extends Cache> resolveCaches(CacheOperationInvocationContext<?> context) {
        Collection<Cache> caches = new ArrayList<>();
        if(context.getTarget().getClass() == GatewayRepository.class){
            if(context.getMethod().getName().equals("findByBulkId")){
                caches.add(cacheManager.getCache("gatewayCache"));
            }
        }

        return caches;
    }
}

In this step, cache name is

gatewayCache

which is defined solely in the cacheresolver and it can be omitted in the annotation side.

After this step, you should register CacheResolver:

@Configuration
@EnableCaching
public class CacheConfiguration extends CachingConfigurerSupport {

    @Bean
    @Override
    public CacheManager cacheManager() {
         // Desired CacheManager
    }

    @Bean
    @Override
    public CacheResolver cacheResolver() {
        return new CustomCacheResolver(cacheManager());
    }
}

And as the last step, you should specify CustomCacheResolver in one of @Cacheable, @CachePut, @CacheConfig etc. annotations.

@Cacheable(cacheResolver="cacheResolver")

You can look here for code samples



来源:https://stackoverflow.com/questions/28985340/spring-cache-with-custom-cacheresolver

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!