Spring Webflux - 延迟初始化的内存缓存

Spring Webflux - lazily initialized in-memory cache

有人可以帮我找到 SpringWebflux 中有状态服务的正确模式吗?我有一个与外部 API 通信的 REST 服务,需要在第一次调用期间从 API 获取身份验证令牌并将其缓存以在所有下一次调用中重用。目前我有一个有效的代码,但并发调用会导致多个令牌请求。有没有办法处理并发?

@Service
@RequiredArgsConstructor
public class ExternalTokenRepository {

    private final WebClient webClient;
    
    private Object cachedToken = null;
    
    public Mono<Object> getToken() {
        if (cachedToken != null) {
            return Mono.just(cachedToken);
        } else {
            return webClient.post()
                //...
                .exchangeToMono(response -> {
                    //...
                    return response.bodyToMono(Object.class)
                })
                .doOnNext(token -> cachedToken = token)
        }
    }
}

更新:我收到的令牌有一些过期时间,我需要在一段时间后刷新它。刷新请求也应该只调用一次。

您可以在构造函数中初始化Mono并使用cache运算符:

@Service
public class ExternalTokenRepository {
    private final Mono<Object> cachedToken;

    public ExternalTokenRepository(WebClient webClient) {
        this.cachedToken = webClient.post()
                //...
                .exchangeToMono(response -> {
                    //...
                    return response.bodyToMono(Object.class);
                })
                .cache(); // this is the important part
    }

    public Mono<Object> getToken() {
        return cachedToken;
    }
}

更新: cache 运算符还支持基于 return 值的 TTL:https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Mono.html#cache-java.util.function.Function-java.util.function.Function-java.util.function.Supplier-