防止Spring WebFlux WebClient在新订阅时执行新的交换

问题描述 投票:0回答:1

DefaultWebClientexchange实现为:

@Override
public Mono<ClientResponse> exchange() {
    ClientRequest request = (this.inserter != null ?
            initRequestBuilder().body(this.inserter).build() :
            initRequestBuilder().build());
    return Mono.defer(() -> exchangeFunction.exchange(request)
            .checkpoint("Request to " + this.httpMethod.name() + " " + this.uri + " [DefaultWebClient]")
            .switchIfEmpty(NO_HTTP_CLIENT_RESPONSE_ERROR));
}

如您在上面看到的,exchangeFunction.exchange调用由Mono.defer包裹,因此,只要有一些订阅返回的Mono<ClientResponse>,就会执行该调用。

但是,在我非常具体的用例中,由于下面的简化代码,我不想重新执行交换:

final WebClient webClient = WebClient.create("http://some-base-url");
final AtomicReference<Mono<ClientResponse>> responseRef = new AtomicReference<>(null);
Flux.fromIterable(Arrays.asList(1, 2, 3))
    .flatMap(num -> {
        if (...some condition...) {
            return responseRef.updateAndGet(response -> response == null 
                                                        ? webClient.get().uri("/some-path").exchange()
                                                        : response)
                              .flatMap(response -> {...do something with num and response...});
        } else {
            return Mono.just(...something...);
        }
    })
    ...

正如您在我的用例中所看到的,我尝试使用AtomicReference延迟获取Mono<ClientResponse>,以便不会一次又一次发出HTTP请求。

这不符合预期,因为订阅flatMap发布的Mono<ClientResponse>的带有数字和响应的exchange()会一次又一次触发其内部exchangeFunction.exchange

我可以用某些内容包装已发布的Mono<ClientResponse>来抵消Mono.defer的影响吗?还是在不更改用例代码结构的情况下解决该问题?

java spring-webflux project-reactor reactive-streams spring-webclient
1个回答
0
投票

您可以执行以下操作:

© www.soinside.com 2019 - 2024. All rights reserved.