I am working on a large Spring Boot 2.1.5.RELEASE application, using Caffeine as a cache provider. To prevent I/O bottlenecks, I am using a Caffeine LoadingCache<K,V>
in (essentially) the following way:
LoadingCache<K, V> cache = Caffeine.newBuilder()
.refreshAfterWrite(1, TimeUnit.MINUTES)
.build(loadStuffOverHttp());
As far as I know, I cannot use refresh-after-write functionality without using LoadingCache
.
However, LoadingCache
does not implement Spring's Cache
. This means I cannot rely on @Bean
methods to register my caches, which each need to be configured differently. Being registered in the Spring context would, in theory, allow them to be used in conjunction with Spring's @Cacheable
annotation.
From what I can see from the source code for CaffeineCacheConfiguration.java, I cannot rely on Spring Boot's auto-configuration either. Beans of type CaffeineCache
(Spring's cache adapter pattern for Caffeine's Cache<K,V>
) are registered automatically, but the adapter forces me to use <Object, Object>
as the generic types of my CacheLoader<K, V>
. I only want to do this as a last resort.
This SO question shows it is possible to configure different caches programmatically:
Just expose your custom caches as beans. They are automatically added to the
CaffeineCacheManager
.
However, doing this with LoadingCache<K, V>
(with arbitrary K
, V
, not <Object, Object>
) seems to be harder.
This SO question seems to indicate doing it with a SimpleCacheManager
instead of a CaffeineCacheManager
is possible - but using this solution requires the CacheLoader
definition to be available to the Cache
bean. This may easily require the injection of the service using the cache via @Cacheable
in the first place, for example in the case of an expensive HTTP call. It also seems like a solution prone to dependency cycles, but please correct me if this is not the case.
Question
What is the proper way to define a Caffeine LoadingCache<K, V>
for use with Spring's @Cacheable
?