My configuration:
@Bean
public CaffeineCacheManager cacheManager() {
return new CaffeineCacheManager();
}
@Bean
public CaffeineCache testCache() {
return new CaffeineCache("test_cache",
Caffeine.newBuilder()
.maximumSize(10000)
.expireAfterAccess(30, TimeUnit.SECONDS)
.expireAfterWrite(30, TimeUnit.SECONDS)
.recordStats()
.build());
}
test code:(read cache 3 times in a row with 45 seconds pause between reads)
static int value = 1;
...
Cache testCache = cacheManager.getCache("test_cache");
System.out.println("read " + testCache.get("myKey", () -> value++));
try {
Thread.sleep(45000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("read " + testCache.get("myKey", () -> value++));
try {
Thread.sleep(45000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("read " + testCache.get("myKey", () -> value++));
Actual result:
read 1
read 1
read 1
Expected result: Cache is evicted after 30 seconds:
read 1
read 2
read 3
What do I wrong ?
How to fix ?
Just fyi, CaffeineCacheManager
and CaffeineCache
are Spring wrappers around the real Caffeine cache.
org.springframework.cache.caffeine
.CaffeineCache
implements org.springframework.cache
.Cache
(emphasis on packages of both)
As to your question, CaffeineCacheManager
returned from your @Bean
has NO caches actually. So when you call cacheManager.getCache("test_cache")
, you get a cache created by Spring on the fly, called a dynamic cache. And this cache's expireAfterAccess
and expireAfterWrite
are not set. Hence, the 1
you put in it is never evicted.
To get expected behavior, you need to add CaffeineCache
to the cache manager. Check my answer.