Java Spring boot WebClient真的是异步的吗?
WebClient是一种反应式客户端,它提供了RestTemplate的替代方案。 据说它是异步的 但我对以下代码表示怀疑:Java Spring boot WebClient真的是异步的吗?,java,spring-boot,asynchronous,spring-webflux,Java,Spring Boot,Asynchronous,Spring Webflux,WebClient是一种反应式客户端,它提供了RestTemplate的替代方案。 据说它是异步的 但我对以下代码表示怀疑: WebClient.create() .method(HttpMethod.GET) .uri("http://localhost:8080/testApi") .retrieve() .bodyToMono(String.class) 它什么也不做。没有发送任何http请
WebClient.create()
.method(HttpMethod.GET)
.uri("http://localhost:8080/testApi")
.retrieve()
.bodyToMono(String.class)
它什么也不做。没有发送任何http请求。看来它没有触发。除非我通过添加.block()
触发它。但它使事情不“异步”
另外,我知道的是使用.subscribe()
使事情看起来是异步的
但是WebClient是为此而设计的吗?使用WebClient的最佳实践是什么
WebClient
使用Reactor Netty
为Java提供一个完全异步的NIO网络库
使用.block()
,您将阻塞调用线程,这是不需要的。对于I/O调用,应该使用.flatMap
,它订阅内部流,并在结果到达时动态合并结果。例如,我会:
Mono.just(httpRequest)
.flatMap(request -> request.exchange().bodyToMono(String.class))
.map(response -> doWhateverToTheResponse(response))
.subscribeOn(Schedulers.elastic())
.subscribe();
请注意,.flatMap()
现在将订阅内部流。当响应返回时,它将进入映射
,流将继续。当流在elastic
线程上启动时,调用线程将变得自由
除非绝对需要,否则切勿使用.block()
。使用它的一个用例:卡夫卡的轮询循环。您希望确保在循环使用下一组记录之前已经处理了一组记录.block()
确保轮询线程保持阻塞状态,除非处理所有记录
编辑:几个月前,我在.flatMap()
上写了一篇小文章。我觉得写得很好,你可以看看这里:
是的,当然web客户端就是为此而设计的。它返回反应类型(Flux、Mono),触发请求发送的方式以及访问它们的响应的方式是订阅。这是反应流的基本原理。反应堆用户指南写得非常好。你应该读一读。如果你想阻止,你可以。但这并不意味着你必须这么做。确实如此。也不阻塞。这似乎不是WebClient的错,而是有人需要阅读反应式编程——也许启动调用线程就可以了。I/O调用将在一个弹性线程上进行,该线程针对I/O进行了优化。当然,该线程将变得空闲,并且Netty将切换到自己的线程池。这个例子更像是一个例证。@coast\u soul这回答了你的问题吗?