gpt4 book ai didi

java - 在现代 Spring 中应该如何同步 http 请求?

转载 作者:行者123 更新时间:2023-12-04 11:43:28 25 4
gpt4 key购买 nike

长期以来,Spring一直在推荐RestTemplate用于同步 http 请求。但是,现在文档说:

NOTE: As of 5.0 this class is in maintenance mode, with only minor requests for changes and bugs to be accepted going forward. Please, consider using the org.springframework.web.reactive.client.WebClient which has a more modern API and supports sync, async, and streaming scenarios.


但是我一直没能看到推荐如何使用 WebClient用于同步场景。 documentation里有这个:

WebClient can be used in synchronous style by blocking at the end for the result


我已经看到一些代码库到处都是使用 .block() 。然而,我的问题是,有了一些响应式框架的经验,我逐渐明白阻塞响应式调用是一种代码味道,应该只用于测试。例如 this page

Sometimes you can only migrate part of your code to be reactive, and you need to reuse reactive sequences in more imperative code.

Thus if you need to block until the value from a Mono is available, use Mono#block() method. It will throw an Exception if the onError event is triggered.

Note that you should avoid this by favoring having reactive code end-to-end, as much as possible. You MUST avoid this at all cost in the middle of other reactive code, as this has the potential to lock your whole reactive pipeline.


那么有没有什么我错过的东西可以避免 block()s 但允许你进行同步调用,或者真的在任何地方使用 block() ?
或者 WebClient API 的意图是暗示人们不应该再在代码库中的任何地方进行阻塞?由于 WebClient 似乎是 Spring 提供的 future http 调用的唯一替代方案,因此将来在整个代码库中使用非阻塞调用并更改代码库的其余部分以适应它是唯一可行的选择吗?
有相关问题 here但它只关注发生的异常,而我有兴趣听到一般应该是什么方法。

最佳答案

首先根据WebClient Java docs

public interface WebClientNon-blocking, reactive client to perform HTTP requests, exposing a fluent, reactive API over underlying HTTP client libraries such asReactor Netty. Use static factory methods create() or create(String),or builder() to prepare an instance.


所以 webClient 不是为了以某种方式阻塞而创建的。
然而,webClient 返回的响应可以是 <T> reactor.core.publisher.Flux<T> 类型的和其他类型的时间 <T> reactor.core.publisher.Mono<T> . reactor 项目中的 Flux 和 Mono 是具有阻塞方法的那些。 ResponseSpec from WebClient.
WebClient 被设计为响应式(Reactive)客户端。
正如您可能从其他语言的其他响应式(Reactive)库中看到的那样,例如 RxJs for javascript响应式(Reactive)编程通常基于函数式编程。
这里会发生什么 FluxMono来自 reactor项目是他们允许您制作 block()以便在不需要函数式编程的情况下进行同步执行。
这是 article 的一部分我觉得很有趣

Extractors: The Subscribers from the Dark Side

There is another way tosubscribe to a sequence, which is to call Mono.block() orMono.toFuture() or Flux.toStream() (these are the "extractor"methods — they get you out of the Reactive types into a less flexible,blocking abstraction). Flux also has converters collectList() andcollectMap() that convert from Flux to Mono. They don’t actuallysubscribe to the sequence, but they do throw away any control youmight have had over the suscription at the level of the individualitems.

Warning A good rule of thumb is "never call an extractor". There aresome exceptions (otherwise the methods would not exist). One notableexception is in tests because it’s useful to be able to block to allowresults to accumulate. These methods are there as an escape hatch tobridge from Reactive to blocking; if you need to adapt to a legacyAPI, for instance Spring MVC. When you call Mono.block() you throwaway all the benefits of the Reactive Streams


那么你可以不使用 block() 进行同步编程吗?操作?
您可以但是你必须从函数式编程的角度考虑
为您的应用程序。
例子
   public void doSomething1( ) {
webClientCall_1....subscribe( response1 -> {

...do something else ...
webClientCall_2....subscribe( response2 -> {
...do something else more with response1 and response2 available here...
});
});
}
这称为订阅 回调 hell .您可以使用 .block() 避免它方法,但再次如所提供的文章所述 他们抛弃了那个库的 react 性 .

关于java - 在现代 Spring 中应该如何同步 http 请求?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69113047/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com