Пружинный кеш с кастомным кешом
Я хочу иметь динамические имена кеша, а весна 4.1 позволяет
Начиная с Spring 4.1, атрибут value аннотаций кэша больше не является обязательным, поскольку эта конкретная информация может быть предоставлена CacheResolver независимо от содержимого аннотации.
Обратите внимание, как я поставил параноидально cacheResolver
на всех возможных уровнях:
@Cacheable(cacheResolver = "defaultCacheResolver")
@CacheConfig(cacheResolver = "defaultCacheResolver")
public interface GatewayRepository extends CrudRepository<Gateway, Integer> {
@Cacheable(cacheResolver = "defaultCacheResolver")
Gateway findByBulkId(int bulkId);
}
Spring 4.1.5 по-прежнему не может проверить конфигурацию с ошибкой: 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 ответ
Я думаю, вы должны указать имя кэша где-то в вашем коде.
В основном случае имя кэша указывается в аннотациях @Cacheable, @CachePut или @CacheEvict.
@Cacheable (cacheNames = "myCache")
Вы также можете указать это в @CacheConfig, который является аннотацией на уровне класса.
@CacheConfig (cacheNames = "myCache")
Если вам нужен более гибкий механизм кэширования, вы можете использовать CacheResolver. В этом случае вы должны создать свой собственный CacheResolver. Что-то вроде этого:
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;
}
}
На этом этапе имя кэша
gatewayCache
который определяется исключительно в кеш-резольвере и может быть опущен на стороне аннотации.
После этого шага вы должны зарегистрировать CacheResolver:
@Configuration
@EnableCaching
public class CacheConfiguration extends CachingConfigurerSupport {
@Bean
@Override
public CacheManager cacheManager() {
// Desired CacheManager
}
@Bean
@Override
public CacheResolver cacheResolver() {
return new CustomCacheResolver(cacheManager());
}
}
И как последний шаг, вы должны указать CustomCacheResolver в одной из аннотаций @Cacheable, @CachePut, @CacheConfig и т. Д.
@Cacheable(cacheResolver="cacheResolver")
Вы можете посмотреть здесь примеры кода