Сегодня меня попросили установить время истечения срока действия кэша для некоторых ключей, используемых нашим приложением, поэтому я быстро начал искать все опции, предоставляемые нотацией Spring @Cacheable, чтобы установить время истечения или время жизни. Поскольку Spring не предоставляет ни одной настраиваемой опции для ее достижения, я создаю одну реализацию, использующую аннотацию @Scheduled с фиксированной задержкой, следующим образом:
1
2
3
4
|
@CacheEvict (allEntries = true , cacheNames = { "EMPLOYEE_" , "MANAGER_" }) @Scheduled (fixedDelay = 30000 ) public void cacheEvict() { } |
Теперь проблема в том, что я хочу, чтобы имена кэша, а также фиксированный период времени задержки заполнялись из значений среды вместо жестко закодированных значений. Чтобы добиться того же, я объявил переменные (заполняемые из файла свойств) на уровне класса и заполнил значения ключа в аннотации, которая заставила IDE жаловаться, что значения должны быть постоянными, как показано ниже:
«Значение атрибута аннотации CacheEvict.cacheNames должно быть постоянным выражением»
Затем я начал искать другие варианты получения значений для ключей из среды и натолкнулся на элемент fixedDelayString нотации @Scheduled, который помог мне достичь своей цели, а именно:
1
2
3
|
@Scheduled (fixedDelayString = "${couchbase.cache.flush.fixed.delay}" ) public void cacheEvict() { } |
Поиск аналогичного элемента для аннотации @CacheEvict , который, к сожалению, недоступен, дал мне подсказку после прочтения комментария об ошибке SPR-10778, в котором говорится:
«Абстракция кэша теперь поддерживает абстракцию CacheResolver, и ее можно указывать глобально, для каждого класса и / или для конкретной операции. CacheResolver дает вам возможность вычислять кэши для использования в коде, чтобы вы имели всю необходимую вам гибкость ».
Как говорит ошибка, чтобы использовать CacheResolver для динамического заполнения имен кэша, я использовал его реализацию AbstractCacheResolver для получения имен кэша из среды следующим образом:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
@Value ( "#{'${couchbase.cache.flush}'}" ) private String couchbaseCacheFlush; @Bean (name = "customCacheResolver" ) public CacheResolver cacheResolver() { CacheResolver cacheResolver = new AbstractCacheResolver(cacheManager()) { @Override protected Collection<String> getCacheNames( CacheOperationInvocationContext<?> context) { return Arrays.asList(couchbaseCacheFlush.split( "," )); } }; return cacheResolver; } |
Модификация cacheEvict () для использования настраиваемого преобразователя кэша вместо имен кэша завершила мою задачу на следующий день:
1
2
3
4
|
@CacheEvict (allEntries = true , cacheResolver = "customCacheResolver" ) @Scheduled (fixedDelayString = "${couchbase.cache.flush.fixed.delay}" ) public void cacheEvict() { } |
Полный исходный код доступен на github .
Ссылка: | Установка TTL для @Cacheable — Spring от нашего партнера JCG |