Spring 带有内存缓存的 WebFlux

Spring WebFlux with in memory cache

我正在使用 Spring 网络通量和番石榴缓存。在某些示例中,他们使用 CacheMono.lookup 从缓存中检索值。我在同一行上试过并有以下代码。

CacheMono.lookup(key -> Mono.justOrEmpty(guavaCache.get(id, PhoneNumber.class))
            .map(Signal::next), id)
            .onCacheMissResume(() -> {
              LOGGER.info("fetch from db");
              return phoneNumberRepository.findById(id);})
            .andWriteWith((key, signal) -> Mono.fromRunnable(() ->
                Optional.ofNullable(signal.get())
                    .ifPresent(value -> {
                      if(value == null){
                        LOGGER.info("value is null");
                      }
                      LOGGER.info("value is not null "+value);
                      guavaCache.put(key, value);}))))

对于当 guava 缓存不包含它从 db 获取并存储到缓存中的值时的初始流程。但是对于同一个键,当我再次发送请求时,缓存中有该键的值。但是 CacheMono.lookup 仍在执行从 db ( I am seeing LOGGER.info("fetch from db");. 获取数据,但同时我没有看到日志 LOGGER.info("value is not null "+value); 我对这种行为感到困惑。为什么onCacheMissResume在缓存已经有数据的情况下被调用了2次

您看到 LOGGER.info("fetch from db") 因为每次 CacheMono 创建 Mono<PhoneNumber> 从数据库中获取时都会调用它。但是如果该值存在于您的缓存中,则此 Mono<PhoneNumber> 将不会被订阅。

您可以通过记录 onSubscribe 事件来检查它:

.onCacheMissResume(() -> {
    LOGGER.info("fetch from db");
    return phoneNumberRepository.findById(id)
        .doOnSubscribe(ignored -> LOGGER.info("really fetching from db"));
})