掌握 Spring Boot 中的 WebClient:何时以及为何使用它而不是 RestTemplate

在开发 Spring Boot 应用程序时,与 RESTful Web 服务进行通信是一项常见需求。从历史上看,开发人员已将RestTemplate用于此目的。然而,随着反应式编程的出现和对更高效资源利用的需求,WebClient已成为首选。本文探讨了RestTemplateWebClient之间的差异,并通过实际示例强调了为什么 WebClient 更适合现代应用程序。

何时使用 RestTemplate?

RestTemplate的定义:

RestTemplate是 Spring Framework 提供的同步、阻塞客户端,用于使用 RESTful Web 服务。它执行请求并等待响应返回。虽然它简单且使用广泛,但其阻塞特性使其不太适合高吞吐量或低延迟应用程序。

RestTemplate 的主要特点:

  • 同步和阻塞。
  • 易于用于基本 HTTP 请求。
  • 与传统 Spring 应用程序良好集成。

尽管WebClient越来越受欢迎,但RestTemplate仍然是许多 Spring Boot 应用程序中广泛使用的选项,尤其是在传统的同步架构中。以下是使用RestTemplate仍然有效且通常更可取的场景。

1.同步应用程序

如果您的应用程序设计为同步、阻塞系统,其中每个操作都等待前一个操作完成,则RestTemplate就足够了,并且使用起来更简单。示例包括:

  • 不使用反应式或异步范例的遗留系统。
  • 流量低且可扩展性需求最小的内部工具或系统。

2.简单用例

对于简单的用例,例如发出一次性 HTTP 请求、下载小文件或将数据发布到服务,RestTemplate提供了易于使用的功能:

  • 快速实现CRUD操作。
  • 与现有的基于 Spring MVC 的应用程序集成。

3. 遗留系统

许多较旧的应用程序是在 WebClient 出现之前构建的,并且严重依赖 RestTemplate。重构这些应用程序以使用 WebClient 可能需要付出巨大努力,但直接好处却微乎其微:

  • 遵循单片架构的应用程序。
  • 没有性能瓶颈的系统,不需要非阻塞 I/O。

4. 有限的并发要求

在并发要求较低、不需要担心资源利用率的应用程序中,RestTemplate就足够了:

  • 用户数有限的企业内部应用程序。
  • 批处理作业或 ETL 系统定期进行 HTTP 调用。

5. 测试和原型设计

对于快速原型设计或测试 API,RestTemplate 通常因其简单性和低设置开销而受到青睐。

RestTemplate 为何被广泛使用?

  1. 历史意义
  • RestTemplate在 Spring 生态系统中很早就被引入,并在响应式编程兴起之前成为 Spring 应用程序中 HTTP 通信的标准。
  • 多年来,它一直是 Spring 中使用 REST API 的默认选择,许多开发人员都熟悉它。

2.易于使用

  • RestTemplate 的简单 API 允许开发人员以最少的配置执行常见的 HTTP 操作GET,如POST、、PUTDELETE

3.强大的生态系统支持

许多 Spring Boot 教程、指南和示例都使用了 RestTemplate,确保开发人员能够获得丰富的资源和社区支持。

4.同步性质

  • 它的阻塞行为与传统编程范式自然一致,使得开发人员可以直观地从桌面或单片应用程序过渡到 Web 服务。

5.成熟稳定

  • RestTemplate 是一个成熟稳定的库,使其成为许多用例的可靠选择。

何时使用 WebClient?

WebClient的定义:

WebClient是作为 Spring WebFlux 框架的一部分引入的非阻塞、响应式 Web 客户端。它旨在支持异步和流式传输场景,非常适合需要高并发性和可扩展性的应用程序。

WebClient 的主要特点:

  • 异步和非阻塞。
  • 支持同步和反应式编程。
  • 适用于流媒体和实时场景。
  • 内置对函数式编程的支持。

WebClient是Spring WebFlux模块中引入的一款功能强大的工具,旨在处理异步、非阻塞 HTTP 请求。它的多功能性、效率和现代设计使其成为各种应用程序的理想选择。下面详细讨论了 WebClient 大放异彩且是推荐选择的场景。

1. 反应式和非阻塞应用程序

WebClient 是开发反应式应用程序的首选。反应式编程旨在通过利用非阻塞 I/O 高效处理大量并发请求。在以下情况下使用 WebClient:

  • 反应式 API:如果您的应用程序使用ReactorRxJava或其他反应式框架,则 WebClient 可以无缝集成。
  • 事件驱动架构:依赖于事件的系统(例如物联网平台)受益于 WebClient 的异步功能。

例子

public Mono<User> fetchUser(String userId) {fetchUser(String userId) {return WebClient.create().get().uri("https://api.example.com/users/{id}", userId).retrieve().bodyToMono(User.class);
}

2. 微服务通信

在微服务架构中,服务通常需要相互通信。WebClient 支持高效、高吞吐量的服务间通信。它允许:

  • 并发请求:同时发送多个请求而不阻塞线程。
  • 低延迟响应:以缩短的响应时间处理实时数据。

例子

public Flux<Order> fetchUserOrders(String userId) {Order> fetchUserOrders(String userId) {return WebClient.create().get().uri("https://orderservice.com/orders?userId=" + userId).retrieve().bodyToFlux(Order.class);
}

3. 高并发要求

对于需要处理许多同时请求的应用程序,WebClient 是理想的选择:

  • 与 RestTemplate 等阻塞客户端相比,它使用更少的线程,从而具有更好的可扩展性。
  • 适用于拥有数千名用户的应用程序或在受限资源上运行的服务。

用例示例

  • 拥有数百万用户的社交媒体平台。
  • 电子商务平台在销售活动期间处理大量并发请求。

 

4. 流和实时数据

WebClient 擅长处理流数据和服务器发送事件 (SSE)。对于需要以下功能的应用程序,请使用 WebClient:

  • 数据流:例如,使用实时股票价格更新或传感器数据。
  • 长连接:处理聊天或实时仪表板等应用程序的 WebSocket 或 SSE。

例子

public Flux<StockPrice> streamStockPrices() {return WebClient.create().get().uri("https://api.example.com/stock-prices/stream").retrieve().bodyToFlux(StockPrice.class);
}

5. 处理大型有效载荷

处理大文件上传/下载或流式传输大数据集的应用程序应该使用 WebClient,因为它具有高效的资源利用率:

  • 由于其非阻塞 I/O,可以实现高效的内存处理。
  • 支持流数据块,无需将整个内容加载到内存中。

例子

public Flux<DataChunk> downloadLargeFile () {return WebClient.create().get ( ).uri( "https://api.example.com/largefile" ).retrieve().bodyToFlux(DataChunk.class ) ;
}

6. 对遗留系统进行现代化改造

随着系统的发展,传统的同步应用程序通常会被现代化为异步、反应式系统。WebClient 非常适合此类转换:

  • 与传统同步 API 无缝协作,同时支持反应式设计。
  • 通过允许系统的某些部分具有反应能力来实现部分现代化。

7. 容错和弹性

WebClient 与Resilience4j等库集成,以提供容错、弹性的通信:

  • 重试:自动重试失败的请求。
  • 断路器:防止互连服务中发生级联故障。
  • 超时:配置超时以妥善处理缓慢的响应。

例子

import io.github.resilience4j.circuitbreaker.CircuitBreaker;
import reactor.core.publisher.Mono;CircuitBreaker circuitBreaker = CircuitBreaker.ofDefaults("myService");public Mono<User> fetchUserWithResilience(String userId) {return WebClient.create().get().uri("https://api.example.com/users/{id}", userId).retrieve().bodyToMono(User.class).transformDeferred(CircuitBreakerOperator.of(circuitBreaker));
}

8. 安全和代理管理

WebClient 为安全通信提供了强大的支持:

  • OAuth2 集成:与 Spring Security 协作处理 OAuth2 令牌管理。
  • 自定义身份验证:配置自定义标头或令牌以实现安全通信。

例子

public Mono<User> fetchUserWithToken(String userId, String token) {fetchUserWithToken(String userId, String token) {return WebClient.builder().defaultHeader(HttpHeaders.AUTHORIZATION, "Bearer " + token).build().get().uri("https://api.example.com/users/{id}", userId).retrieve().bodyToMono(User.class);
}

9. 测试和模拟 API

WebClient 适合测试目的,因为它与WireMock等模拟服务器集成:

  • 模拟 API 响应以进行集成测试。
  • 测试失败场景,例如超时或错误代码。

例子

@Test
public void testFetchUser() {WireMockServer wireMockServer = new WireMockServer();wireMockServer.start();wireMockServer.stubFor(get(urlEqualTo("/users/1")).willReturn(aResponse().withHeader("Content-Type", "application/json").withBody("{\"id\":1,\"name\":\"John Doe\"}")));WebClient webClient = WebClient.create(wireMockServer.baseUrl());Mono<User> user = webClient.get().uri("/users/1").retrieve().bodyToMono(User.class);StepVerifier.create(user).expectNextMatches(u -> u.getName().equals("John Doe")).verifyComplete();wireMockServer.stop();
}

10.跨平台集成

WebClient 的灵活性使其能够与不同的平台和协议集成:

  • 使用 REST API、GraphQL 端点或 SOAP 服务。
  • 与 AWS、Azure 或 Google Cloud 等云平台通信。

为什么在 Spring Boot 应用程序中使用 WebClient 而不是 RestTemplate?

在开发 Spring Boot 应用程序时,与 RESTful Web 服务进行通信是一项常见需求。从历史上看,开发人员已将RestTemplate用于此目的。然而,随着反应式编程的出现和对更高效资源利用的需求,WebClient已成为首选。本文探讨了RestTemplateWebClient之间的差异,并通过实际示例强调了为什么 WebClient 更适合现代应用程序。

为什么选择 WebClient 而不是 RestTemplate?

  1. 非阻塞 I/O:WebClient 使用非阻塞模型,这意味着在等待响应时线程不会被阻塞。当同时进行多个 API 调用时,这尤其有用。
  2. 支持反应流:WebClient 与ReactorRxJava等反应库无缝集成,使其适用于现代反应架构。
  3. 更好的可扩展性:非阻塞行为允许 WebClient 同时处理更多请求而不会耗尽服务器线程。
  4. 现代且可扩展:WebClient 更加灵活且功能丰富,支持流式传输大文件、处理 WebSocket 连接和多部分请求等高级用例。

实时示例:比较 RestTemplate 和 WebClient

示例 1:从外部 API 获取数据

使用 RestTemplate

import org.springframework.web.client.RestTemplate;public class RestTemplateExample {private RestTemplate restTemplate = new RestTemplate();public String getUserDetails(String userId) {String url = "https://api.example.com/users/" + userId;return restTemplate.getForObject(url, String.class);}
}

使用WebClient

import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;public class WebClientExample {private WebClient webClient = WebClient.create();public Mono<String> getUserDetails(String userId) {String url = "https://api.example.com/users/" + userId;return webClient.get().uri(url).retrieve().bodyToMono(String.class);}
}

主要区别

  • RestTemplate 需要明确管理线程,增加了复杂性。
  • WebClient 本身可以处理并发,从而减少样板代码。

从 RestTemplate 迁移到 WebClient

要在您的项目中从 RestTemplate 切换到 WebClient:

  1. 添加依赖项:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

 

2. 用被动调用替代同步调用。

3. 更新测试来处理诸如Mono和之类的反应数据类型Flux

结论

WebClient 是一款功能强大、用途广泛且现代化的 Spring Boot 应用程序 HTTP 客户端,可帮助开发人员构建高效、反应灵敏且可扩展的系统。它最适合高并发环境、实时数据处理、微服务和现代反应性应用程序。对于今天开始的项目或迁移到反应性范式的项目,WebClient 是明智的选择

RestTemplate 更简单,可能适用于小型应用程序或旧式系统,而WebClient则是现代、可扩展且反应灵敏的 Spring Boot 应用程序的首选。它提供了一种与 Web 服务交互的更有效方式,尤其是在需要高并发性和低延迟的场景中。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/63579.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

主曲率为常数时曲面分类

主曲率为常数 ⇔ K , H \Leftrightarrow K,H ⇔K,H 为常数&#xff0c;曲面分类&#xff1a; 1.若 k 1 k 2 0 k_1k_20 k1​k2​0,则 S S S为全脐点曲面——平面的一部分&#xff1b; 2.若 k 1 k 2 ≠ 0 k_1k_2\neq0 k1​k2​0,则 S S S为全脐点曲面——球面的一部分&…

asp.net core发布配置端口号,支持linux

方式一&#xff0c;修改配置文件 appsettings.json 找到文件 appsettings.json&#xff0c; 添加如下节点配置&#xff0c;在linux环境需要设置0.0.0.0才可以正常代表本机&#xff0c;然后被其他机器访问&#xff0c;此处设置端口8000&#xff0c; "Kestrel": {&quo…

【安当产品应用案例100集】033-安当TDE透明加密在移动存储加密中的应用案例

背景介绍 随着移动互联网的普及&#xff0c;企业和个人越来越依赖移动存储设备&#xff0c;如U盘、移动硬盘以及云存储服务进行数据的存储和传输。然而&#xff0c;这种便捷性也带来了数据安全的隐患。如何确保存储在移动设备上的数据不被非法访问和泄露&#xff0c;成为企业和…

【linux 内存】cat /proc/meminfo、free

cat /proc/meminfo 各字段详解 /proc/meminfo是了解Linux系统内存使用状况的主要接口&#xff0c;我们最常用的”free”、”vmstat”等命令就是通过它获取数据的 &#xff0c;/proc/meminfo所包含的信息比”free”等命令要丰富得多&#xff0c;因此需要了解这些字段的含义。 …

Android HandlerThread、Looper、MessageQueue 源码分析

Android HandlerThread、Looper、MessageQueue 源码分析 简介 在 Android 开发中&#xff0c;大家应该对 HandlerThread 有一定了解。顾名思义&#xff0c;HandlerThread 是 Thread 的一个子类。与普通的 Thread 不同&#xff0c;Thread 通常一次只能执行一个后台任务&#x…

配置PostgreSQL用于集成测试的步骤

在进行软件开发时&#xff0c;集成测试是确保各个组件能够协同工作的关键环节。PostgreSQL作为一种强大的开源数据库系统&#xff0c;常被用于集成测试中。下面将详细介绍如何在不同的环境中配置PostgreSQL以支持集成测试。 1. 选择并安装PostgreSQL 首先&#xff0c;你需要根…

WebRTC搭建与应用(一)-ICE服务搭建

WebRTC搭建与应用(一) 近期由于项目需要在研究前端WebGL渲染转为云渲染&#xff0c;借此机会对WebRTC、ICE信令协议等有了初步了解&#xff0c;在此记录一下&#xff0c;以防遗忘。 第一章 ICE服务搭建 文章目录 WebRTC搭建与应用(一)前言一、ICE是什么&#xff1f;二、什么…

【学习笔记】深入浅出详解Pytorch中的View, reshape, unfold,flatten等方法。

文章目录 一、写在前面二、Reshape&#xff08;一&#xff09;用法&#xff08;二&#xff09;代码展示 三、Unfold&#xff08;一&#xff09;torch.unfold 的基本概念&#xff08;二&#xff09;torch.unfold 的工作原理&#xff08;三&#xff09; 示例代码&#xff08;四&a…

深入理解 MySQL 索引

引言 在数据库管理中&#xff0c;索引&#xff08;Index&#xff09;是提高查询性能的关键技术之一。MySQL 是最流行的关系型数据库管理系统之一&#xff0c;广泛应用于各种规模的应用程序中。本文将深入探讨 MySQL 中的索引概念、类型、工作原理以及最佳实践&#xff0c;帮助…

利用notepad++删除特定关键字所在的行

1、按组合键Ctrl H&#xff0c;查找模式选择 ‘正则表达式’&#xff0c;不选 ‘.匹配新行’ 2、查找目标输入 &#xff1a; ^.*关键字.*\r\n (不保留空行) ^.*关键字.*$ (保留空行)3、替换为&#xff1a;&#xff08;空&#xff09; 配置界面参考下图&#xff1a; ​​…

docker安装和换源

安装&#xff1a; https://www.runoob.com/docker/ubuntu-docker-install.html sudo apt-get remove docker docker-engine docker.io containerd runcsudo apt-get install \apt-transport-https \ca-certificates \curl \gnupg-agent \software-properties-commoncurl -fsS…

CSSmodule的作用是什么

CSS Modules的作用主要体现在以下几个方面&#xff1a; 1. 解决全局样式污染问题 在传统的CSS管理方式中&#xff0c;样式定义通常是全局的&#xff0c;这很容易导致全局样式污染。当多个组件或页面共享同一个样式时&#xff0c;可能会出现样式冲突和覆盖的情况&#xff0c;从…

创建第一个QML项目

文章目录 使用 Qt Creator 创建 Qt Quick 项目详解为什么选择 Qt Creator&#xff1f;1. 打开 Qt Creator2. 选择项目模板3. 设置项目名称与路径4. 定义项目细节5. 配置构建套件6. 检查项目配置7. 编译并运行项目后续操作修改界面添加功能 总结 使用 Qt Creator 创建 Qt Quick …

【k8s集群应用】K8S二进制安装大致步骤(简略版)

文章目录 K8S二进制安装部署etcd测试etcd集群&#xff08;可选&#xff09;恢复etcd数据库 部署master组件部署node组件K8S kubeadm安装关键命令更新kubeadm安装的K8S证书有效期方法一方法二查看证书有效期 K8S二进制安装 部署etcd 使用cfssl工具签发证书和私钥下载解压etcd软…

瑞吉外卖项目学习笔记(二)Swagger、logback、表单校验和参数打印功能的实现

瑞吉外卖项目学习笔记(一)准备工作、员工登录功能实现 文章目录 3 项目组件优化3.1 实现Swagger文档输出3.2 实现logback日志打印3.3 实现表单校验功能3.4 实现请求参数和响应参数的打印 3 项目组件优化 3.1 实现Swagger文档输出 1&#xff09;在application.yml中增加knife4…

leetcode刷题-回溯算法04

代码随想录回溯算法part01| 491.递增子序列、46.全排列、47.全排列II 491.递增子序列46.全排列47.全排列II 491.递增子序列 leetcode题目链接 代码随想录文档讲解 思路&#xff1a; 与上一题不同&#xff0c;不能用used列表&#xff0c;因为这个题不能排序&#xff0c; 在每一…

基于字节大模型的论文翻译(含免费源码)

基于字节大模型的论文翻译 源代码&#xff1a; &#x1f44f; star ✨ https://github.com/boots-coder/LLM-application 展示 项目简介 本项目是一个基于大语言模型&#xff08;Large Language Model, LLM&#xff09;的论文阅读与翻译辅助工具。它通过用户界面&#xff08…

mysql的事务控制和数据库的备份和恢复

事务控制语句 行锁和死锁 行锁 两个客户端同时对同一索引行进行操作 客户端1正常运行 客户端2想修改&#xff0c;被锁行 除非将事务提交才能继续运行 死锁 客户端1删除第5行 客户端2设置第1行为排他锁 客户端1删除行1被锁 客户端2更新行5被锁 如何避免死锁 mysql的备份和还…

Tengine:Nginx二次开发-高性能进化

前言&#xff1a;在当今的互联网时代&#xff0c;Web 服务器的性能和稳定性对于网站的成功至关重要。Nginx 以其高性能和可扩展性而闻名&#xff0c;但有时候&#xff0c;我们需要更多的特性来满足特定的业务需求。Tengine&#xff0c;作为一个由淘宝网发起的 Nginx 二次开发版…

RK3588, FFmpeg 拉流 RTSP, mpp 硬解码转RGB

RK3588 ,基于FFmpeg, 拉取RTSP,使用 mpp 实现硬解码. ⚡️ 传送 ➡️ Ubuntu x64 架构, 交叉编译aarch64 FFmpeg mppRK3588, FFmpeg 拉流 RTSP, mpp 硬解码转RGBRk3588 FFmpeg 拉流 RTSP, 硬解码转RGBRK3588 , mpp硬编码yuv, 保存MP4视频文件.