掌握 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.pswp.cn/web/63579.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/63579.shtml
英文地址,請注明出處:http://en.pswp.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視頻文件.