首页 > 解决方案 > Spring Webflux - 延迟初始化的内存缓存

问题描述

有人可以帮助我在 SpringWebflux 中使用正确的有状态服务模式吗?我有一个 REST 服务,它与外部 API 通信,需要在第一次调用期间从该 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)
        }
    }
}

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

标签: springreactive-programmingspring-webfluxproject-reactor

解决方案


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运算符还支持基于返回值的 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-


推荐阅读