Пружинный кеш с кастомным кешом

Я хочу иметь динамические имена кеша, а весна 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")

Вы можете посмотреть здесь примеры кода

Другие вопросы по тегам