Spring Boot 2 (十):Spring Boot 中的響應式編程和 WebFlux 入門

Spring 5.0 中發佈了重量級組件 Webflux,拉起了響應式編程的規模使用序幕。前端

WebFlux 使用的場景是異步非阻塞的,使用 Webflux 做爲系統解決方案,在大多數場景下能夠提升系統吞吐量。Spring Boot 2.0 是基於 Spring5 構建而成,所以 Spring Boot 2.X 將自動繼承了 Webflux 組件,本篇給你們介紹如何在 Spring Boot 中使用 Webflux 。react

爲了方便你們理解,咱們先來了解幾個概念。git

響應式編程

在計算機中,響應式編程或反應式編程(英語:Reactive programming)是一種面向數據流和變化傳播的編程範式。這意味着能夠在編程語言中很方便地表達靜態或動態的數據流,而相關的計算模型會自動將變化的值經過數據流進行傳播。github

例如,在命令式編程環境中,a=b+c 表示將表達式的結果賦給 a,而以後改變 b 或 c 的值不會影響 a 。但在響應式編程中,a 的值會隨着 b 或 c 的更新而更新。web

響應式編程是基於異步和事件驅動的非阻塞程序,只須要在程序內啓動少許線程擴展,而不是水平經過集羣擴展。redis

用大白話講,咱們之前編寫的大部分都是阻塞類的程序,當一個請求過來時任務會被阻塞,直到這個任務完成後再返回給前端;響應式編程接到請求後只是提交了一個請求給後端,後端會再安排另外的線程去執行任務,當任務執行完成後再異步通知到前端。spring

Reactor數據庫

Java 領域的響應式編程庫中,最有名的算是 Reactor 了。Reactor 也是 Spring 5 中反應式編程的基礎,Webflux 依賴 Reactor 而構建。編程

Reactor 是一個基於 JVM 之上的異步應用基礎庫。爲 Java 、Groovy 和其餘 JVM 語言提供了構建基於事件和數據驅動應用的抽象庫。Reactor 性能至關高,在最新的硬件平臺上,使用無堵塞分發器每秒鐘可處理 1500 萬事件。後端

簡單說,Reactor 是一個輕量級 JVM 基礎庫,幫助你的服務或應用高效,異步地傳遞消息。Reactor 中有兩個很是重要的概念 Flux 和 Mono 。

Flux 和 Mono

Flux 和 Mono 是 Reactor 中的兩個基本概念。Flux 表示的是包含 0 到 N 個元素的異步序列。在該序列中能夠包含三種不一樣類型的消息通知:正常的包含元素的消息、序列結束的消息和序列出錯的消息。當消息通知產生時,訂閱者中對應的方法 onNext(), onComplete()和 onError()會被調用。

Mono 表示的是包含 0 或者 1 個元素的異步序列。該序列中一樣能夠包含與 Flux 相同的三種類型的消息通知。Flux 和 Mono 之間能夠進行轉換。對一個 Flux 序列進行計數操做,獲得的結果是一個 Mono 對象。把兩個 Mono 序列合併在一塊兒,獲得的是一個 Flux 對象。

WebFlux 是什麼?

WebFlux 模塊的名稱是 spring-webflux,名稱中的 Flux 來源於 Reactor 中的類 Flux。Spring webflux 有一個全新的非堵塞的函數式 Reactive Web 框架,能夠用來構建異步的、非堵塞的、事件驅動的服務,在伸縮性方面表現很是好。

非阻塞的關鍵預期好處是可以以小的固定數量的線程和較少的內存進行擴展。在服務器端 WebFlux 支持2種不一樣的編程模型:

  • 基於註解的 @Controller 和其餘註解也支持 Spring MVC
  • Functional 、Java 8 lambda 風格的路由和處理

如圖所示,WebFlux 模塊從上到下依次是 Router Functions、WebFlux、Reactive Streams 三個新組件。

  • Router Functions
    對標準的 @Controller,@RequestMapping 等的 Spring MVC 註解,提供一套 函數式風格的 API,用於建立 Router、Handler 和Filter。
  • WebFlux
    核心組件,協調上下游各個組件提供 響應式編程 支持。
  • Reactive Streams
    一種支持 背壓 (Backpressure) 的 異步數據流處理標準,主流實現有 RxJava 和 Reactor,Spring WebFlux 集成的是 Reactor。

默認狀況下,Spring Boot 2 使用 Netty WebFlux,由於 Netty 在異步非阻塞空間中被普遍使用,異步非阻塞鏈接能夠節省更多的資源,提供更高的響應度。經過比較 Servlet 3.1 非阻塞 I / O 沒有太多的使用,由於使用它的成本比較高,Spring WebFlux 打開了一條實用的通路。

值得注意的是:支持 reactive 編程的數據庫只有 MongoDB, redis, Cassandra, Couchbase

Spring Webflux

Spring Boot 2.0 包括一個新的 spring-webflux 模塊。該模塊包含對響應式 HTTP 和 WebSocket 客戶端的支持,以及對 REST,HTML 和 WebSocket 交互等程序的支持。通常來講,Spring MVC 用於同步處理,Spring Webflux 用於異步處理。

Spring Boot Webflux 有兩種編程模型實現,一種相似 Spring MVC 註解方式,另外一種是基於 Reactor 的響應式方式。

快速上手

添加 webflux 依賴

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

經過 IEDA 的依賴關係圖咱們能夠返現spring-boot-starter-webflux依賴於spring-webflux、Reactor 和 Netty 相關依賴包。

建立 Controller

@RestController
public class HelloController {

    @GetMapping("/hello")
    public Mono<String> hello() {
        return Mono.just("Welcome to reactive world ~");
    }
}

經過上面的示例能夠發現,開發模式和以前 Spring Mvc 的模式差異不是很大,只是在方法的返回值上有所區別。

  • just() 方法能夠指定序列中包含的所有元素。
  • 響應式編程的返回值必須是 Flux 或者 Mono ,二者之間能夠相互轉換。

測試類

@RunWith(SpringRunner.class)
@WebFluxTest(controllers = HelloController.class)
public class HelloTests {
    @Autowired
    WebTestClient client;

    @Test
    public void getHello() {
        client.get().uri("/hello").exchange().expectStatus().isOk();
    }
}

運行測試類,測試用例經過表示服務正常。啓動項目後,訪問地址:http://localhost:8080/hello,頁面返回信息:

Welcome to reactive world ~

證實 Webflux 集成成功。

以上即是 Spring Boot 集成 Webflux 最簡單的 Demo ,後續咱們繼續研究 Webflux 的使用。

示例

全網最全的 Spring Boot 學習示例項目,擊下方連接便可獲取。

示例代碼-github

示例代碼-碼雲

相關文章
相關標籤/搜索