35、使用 WebClient 调用 REST 服务

如果在 classpath 上存在 Spring WebFlux,则还可以选择使用 WebClient 来调用远程 REST 服务。与 RestTemplate 相比,该客户端更具函数式风格并且完全响应式。您可以在 Spring Framework 文档的相关部分中了解有关 WebClient 的更多信息。

Spring Boot 为您创建并预配置了一个 WebClient.Builder。强烈建议将其注入您的组件中并使用它来创建 WebClient 实例。Spring Boot 配置该构建器以共享 HTTP 资源,以与服务器相同的方式反射编解码器设置(请参阅 WebFlux HTTP 编解码器自动配置)等。

以下代码是一个典型示例:

  1. @Service
  2. public class MyService {
  3. private final WebClient webClient;
  4. public MyService(WebClient.Builder webClientBuilder) {
  5. this.webClient = webClientBuilder.baseUrl("http://example.org").build();
  6. }
  7. public Mono<Details> someRestCall(String name) {
  8. return this.webClient.get().uri("/{name}/details", name)
  9. .retrieve().bodyToMono(Details.class);
  10. }
  11. }

35.1、WebClient 运行时

Spring Boot 将自动检测用于驱动 WebClientClientHttpConnector,具体取决于应用程序 classpath 上可用的类库。目前支持 Reactor Netty 和 Jetty RS 客户端。

默认情况下 spring-boot-starter-webflux starter 依赖于 io.projectreactor.netty:reactor-netty,它包含了服务器和客户端的实现。如果您选择将 Jetty 用作响应式服务器,则应添加 Jetty Reactive HTTP 客户端库依赖项 org.eclipse.jetty:jetty-reactive-httpclient。服务器和客户端使用相同的技术具有一定优势,因为它会自动在客户端和服务器之间共享 HTTP 资源。

开发人员可以通过提供自定义的 ReactorResourceFactoryJettyResourceFactory bean 来覆盖 Jetty 和 Reactor Netty 的资源配置 —— 这将同时应用于客户端和服务器。

如果您只希望覆盖客户端选项,则可以定义自己的 ClientHttpConnector bean 并完全控制客户端配置。

您可以在 Spring Framework 参考文档中了解有关 WebClient 配置选项的更多信息

35.2、自定义 WebClient

WebClient 自定义有三种主要方法,具体取决于您希望自定义的程度。

要想自定义的范围尽可能地窄,请注入自动配置的 WebClient.Builder,然后根据需要调用其方法。WebClient.Builder 实例是有状态的:构建器上的任何更改都会影响到之后所有使用它创建的客户端。如果要使用相同的构建器创建多个客户端,可以考虑使用 WebClient.Builder other = builder.clone(); 的方式克隆构建器。

要在应用程序范围内对所有 WebClient.Builder 实例添加自定义,可以声明 WebClientCustomizer bean 并在注入点局部更改 WebClient.Builder

最后,您可以回退到原始 API 并使用 WebClient.create()。在这种情况下,不会应用自动配置或 WebClientCustomizer