Caching in Spring 5 WebFlux
There is an reactor cache add-on which can be used with Spring CacheManager. But, as pointed out by the comments in the accepted answer, currently, the Spring cache APIs(gets and puts) are still blocking. We can only make the program fully reactive until this issue is solved.
Here is the sample code snippet in java. The complete sample project is here in github.
@Service
public class CatServiceImpl implements CatService {
private static final String CACHE_NAME = "sr";
private static final String KEY = "k";
@Autowired
private WebClient client;
@Autowired
private CacheManager cacheManager;
@SuppressWarnings("unchecked")
private Function<String, Mono<List<Signal<CatDto>>>> reader = k -> Mono
.justOrEmpty((Optional.ofNullable((List<CatDto>) (cacheManager.getCache(CACHE_NAME).get(k, List.class)))))
.flatMap(v -> Flux.fromIterable(v).materialize().collectList());
private BiFunction<String, List<Signal<CatDto>>, Mono<Void>> writer = (k, sigs) -> Flux.fromIterable(sigs)
.dematerialize().collectList().doOnNext(l -> cacheManager.getCache(CACHE_NAME).put(k, l)).then();
@Override
public Flux<CatDto> search() {
Flux<CatDto> fromServer = client.get().retrieve().bodyToFlux(CatDto.class);
return CacheFlux.lookup(reader, KEY).onCacheMissResume(fromServer).andWriteWith(writer);
}
}
For now, @Cacheable
doesn't work with Flux
(and Reactor in general).
But regarding your example, each time you call the method, you're creating a new Flux
instance, so naturally, it never caches anything.
To be able to cache results, you need to either convert a Flux
to a list instance, or simply keep reusing one Flux
instance