Spring Cache Abstraction - это абстракция, а не реализация, поэтому она вообще не поддерживает явную настройку TTL, поскольку это особенность реализации.Например, если ваш кеш поддерживается ConcurrentHashMap
, он не может поддерживать TTL "из коробки".
В вашем случае у вас есть 2 варианта.Если вам нужен локальный кеш (т. Е. Каждый экземпляр микросервиса управляет собственным кешем), вы можете заменить Spring Cache Abstraction на Caffeine , официальная зависимость которого предоставляется и управляется Spring Boot.Просто нужно объявить без упоминания версии.
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
</dependency>
Тогда вы можете создать экземпляр кеша следующим образом.Каждый токен, который вы помещаете в кеш, автоматически удаляется в зависимости от вашей конфигурации.
@Service
public class UserTokenManager {
private static Cache<String, String> tokenCache;
@Autowired
private UserTokenManager (@Value("${token.cache.time-to-live-in-seconds}") int timeToLiveInSeconds) {
tokenCache = Caffeine.newBuilder()
.expireAfterWrite(timeToLiveInSeconds, TimeUnit.SECONDS)
// Optional listener for removal event
.removalListener((userName, tokenString, cause) -> System.out.println("TOKEN WAS REMOVED FOR USER: " + userName))
.build();
}
public String getUserToken(String userName){
// If cached, return; otherwise create, cache and return
// Guaranteed to be atomic (i.e. applied at most once per key)
return tokenCache.get(userName, userName -> this.createToken(userName));
}
private String createToken(String userName) {
// call Identity service to acquire tokens
}
}
Опять же, это локальный кеш, что означает, что каждая микросервис будет управлять своим собственным набором токенов.,Поэтому, если у вас есть 5 запущенных экземпляров одного и того же микросервиса, у одного и того же пользователя может быть 5 токенов, лежащих во всех 5 кешах, в зависимости от того, какие экземпляры обрабатывали его запросы.
С другой стороны, если вам нужен распределенный кеш (т. е. несколько экземпляров микросервиса совместно используют один и тот же централизованный кеш), вам нужно взглянуть на EHCache или Hazelcast .В этом случае вы можете продолжать использовать Spring Cache Abstraction и выбрать одну из этих библиотек в качестве своей реализации, объявив CacheManager
из этих библиотек (например, HazelcastCacheManager
).
Затем вы можете взглянуть насоответствующая документация для дальнейшей настройки выбранного вами CacheManager
с TTL для определенных кэшей (например, ваш tokenCache
).В качестве примера я привел простую конфигурацию для Hazelcast.
@Configuration
public class DistributedCacheConfiguration {
@Bean
public HazelcastInstance hazelcastInstance(@Value("${token.cache.time-to-live-in-seconds}") int timeToLiveInSeconds) {
Config config = new Config();
config.setInstanceName("hazelcastInstance");
MapConfig mapConfig = config.getMapConfig("tokenCache");
mapConfig.setTimeToLiveSeconds(timeToLiveInSeconds);
return Hazelcast.newHazelcastInstance(config);
}
@Bean
public CacheManager cacheManager(HazelcastInstance hazelcastInstance) {
return new HazelcastCacheManager(hazelcastInstance);
}
}