I have implemented a cache and now I want to add an expiry time.
How can I set an expiry time in spring boot with @Cacheable
?
This is a code snippet:
@Cacheable(value="forecast",unless="#result == null")
I have implemented a cache and now I want to add an expiry time.
How can I set an expiry time in spring boot with @Cacheable
?
This is a code snippet:
@Cacheable(value="forecast",unless="#result == null")
I use life hacking like this:
@Configuration
@EnableCaching
@EnableScheduling
public class CachingConfig {
public static final String GAMES = "GAMES";
@Bean
public CacheManager cacheManager() {
ConcurrentMapCacheManager cacheManager = new ConcurrentMapCacheManager(GAMES);
return cacheManager;
}
@CacheEvict(allEntries = true, value = {GAMES})
@Scheduled(fixedDelay = 10 * 60 * 1000 , initialDelay = 500)
public void reportCacheEvict() {
System.out.println("Flush Cache " + dateFormat.format(new Date()));
}
}
Note that this answer uses ehcache, which is one of supported Spring Boot cache managers, and arguably one of the most popular.
First you need to add to pom.xml
:
<!-- Spring Framework Caching Support -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
</dependency>
In src/main/resources/ehcache.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<ehcache>
<defaultCache eternal="true" maxElementsInMemory="100" overflowToDisk="false" />
<cache name="forecast"
maxElementsInMemory="1000"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="false"
memoryStoreEvictionPolicy="LRU" />
</ehcache>
From the reference documentation
Directly through your cache provider. The cache abstraction is… well, an abstraction not a cache implementation. The solution you are using might support various data policies and different topologies which other solutions do not (take for example the JDK ConcurrentHashMap) - exposing that in the cache abstraction would be useless simply because there would no backing support. Such functionality should be controlled directly through the backing cache, when configuring it or through its native API.
You cannot specify expiry time with @cacheable notation, since @cacheable does not provide any such configurable option.
However different caching vendors providing spring caching have provided this feature through their own configurations. For example NCache / TayzGrid allows you to create different cache regions with configurable expiration time.
If you have implemented your own cache, you will need to define a way to specify expiration in you cache provider and will also need to incorporate expiration logic in your solution.
I use caffeine-caching, with this configuration for a 60 minute expiration:
spring.cache.cache-names=forecast
spring.cache.caffeine.spec=expireAfterWrite=60m
You can achieve this kind of eviction strategy by making use of @Scheduled
annotation. It is possible to schedule with a fixedRate or even with a cron expression.
@Autowired
CacheManager cacheManager;
public void evictAllCaches() {
cacheManager.getCacheNames().stream()
.forEach(cacheName -> cacheManager.getCache(cacheName).clear());
}
@Scheduled(fixedRate = 6000)
public void evictAllcachesAtIntervals() {
evictAllCaches();
}
Found this Spring cache: Set expiry time to a cache entry.
It uses the spring-boot-starter-cache
dependency and works as expected . You can configure the expiry time for cached objects as well as the max number of cached values.
If you are using Caffeine than you can add the following line in your application.properties
file:
spring.cache.caffeine.spec=expireAfterAccess=300s