Статьи

Установка TTL для @Cacheable — Spring

Сегодня меня попросили установить время истечения срока действия кэша для некоторых ключей, используемых нашим приложением, поэтому я быстро начал искать все опции, предоставляемые нотацией 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 .