I am having trouble understanding how to cache Reactive streams using the spring-data-starter-cache library. From tutorials such as https://www.baeldung.com/spring-webflux-cacheable, I see that they make use of either Mono.cache
or Caffine.newBuilder
to instantiate some type of Map-like cache object that needs to be managed. Seems like the issue stems from @Cacheable
only caching the wrapper and not the actual results itself
// application.yml
spring:
cache:
type: caffeine
caffeine:
spec: maximumSize=1000,expireAfterAccess=3600s
// Code logic
@Cacheable(value = "stuff")
public Mono<String> getInfo(int id) {
return infoProvider.getInfo(id);
}
What do I need to do to fix this to cache the value emitted by the Mono
?
My inital thought is that it could just be a matter of using return infoProvider.getInfo(id).cache();
with some duration, but I was told that this would not work. Why not?
I believe you'll need to build a custom cache using buildAsync
.
Example config
Please note that I'm using expireAfterWrite
because expireAfterAccess
resets the expiration timer every time the entry is accessed, which is not very efficient.
import com.github.benmanes.caffeine.cache.Caffeine;
import org.springframework.cache.CacheManager;
import org.springframework.cache.caffeine.CaffeineCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.concurrent.TimeUnit;
@Configuration(proxyBeanMethods = false)
public class CacheConfig {
@Bean
public CacheManager cacheManager() {
var cacheManager = new CaffeineCacheManager();
cacheManager.registerCustomCache("stuff",
Caffeine.newBuilder()
.expireAfterWrite(1, TimeUnit.HOURS)
.maximumSize(1000)
.buildAsync()); // Note: buildAsync
return cacheManager;
}
}