Spring Boot 2.0 WebFlux 教程 (一) | 入門篇

文章首發自我的公衆號: 小哈學Javahtml

我的網站: www.exception.site/webflux前端

目錄

1、什麼是 Spring WebFluxjava

2、WebFlux 的優點&提高性能?react

3、WebFlux 應用場景git

4、選 WebFlux 仍是 Spring MVC?github

5、異同點web

6、簡單看看 WebFlux 是如何分發請求的面試

7、快速入門spring

  • 7.1 添加 webflux 依賴數據庫

  • 7.2 定義接口

  • 7.3 測試接口

8、總結

9、GitHub 示例代碼

1、什麼是 Spring WebFlux

下圖截自 Spring Boot 官方網站:

Spring Boot 2.0 WebFlux 教程 | 入門篇
Spring Boot 2.0 WebFlux 教程 | 入門篇

結合上圖,在瞭解 Spring WebFlux 以前,咱們先來對比說說什麼是 Spring MVC,這更有益咱們去理解 WebFlux,圖右邊對 Spring MVC 的定義,原文以下:

Spring MVC is built on the Servlet API and uses a synchronous blocking I/O architecture whth a one-request-per-thread model.

翻譯一下,意思以下:

Spring MVC 構建於 Servlet API 之上,使用的是同步阻塞式 I/O 模型,什麼是同步阻塞式 I/O 模型呢?就是說,每個請求對應一個線程去處理。

瞭解了 Spring MVC 以後,再來講說 Spring WebFlux:

上圖左邊,官方給出的定義以下:

Spring WebFlux is a non-blocking web framework built from the ground up to take advantage of multi-core, next-generation processors and handle massive numbers of concurrent connections.

翻譯一下,內容以下:

Spring WebFlux 是一個異步非阻塞式的 Web 框架,它可以充分利用多核 CPU 的硬件資源去處理大量的併發請求。

2、WebFlux 的優點&提高性能?

WebFlux 內部使用的是響應式編程(Reactive Programming),以 Reactor 庫爲基礎, 基於異步和事件驅動,可讓咱們在不擴充硬件資源的前提下,提高系統的吞吐量和伸縮性。

看到這裏,你是否是覺得 WebFlux 可以使程序運行的更快呢?量化一點,好比說我使用 WebFlux 之後,一個接口的請求響應時間是否是就縮短了呢?

抱歉了,答案是否認的! 如下是官方原話:

Reactive and non-blocking generally do not make applications run faster.

WebFlux 並不能使接口的響應時間縮短,它僅僅可以提高吞吐量和伸縮性

3、WebFlux 應用場景

上面說到了, Spring WebFlux 是一個異步非阻塞式的 Web 框架,因此,它特別適合應用在 IO 密集型的服務中,好比微服務網關這樣的應用中。

PS: IO 密集型包括:磁盤IO密集型, 網絡IO密集型,微服務網關就屬於網絡 IO 密集型,使用異步非阻塞式編程模型,可以顯著地提高網關對下游服務轉發的吞吐量。

WebFlux網關
WebFlux網關

4、選 WebFlux 仍是 Spring MVC?

首先你須要明確一點就是:WebFlux 不是 Spring MVC 的替代方案!,雖然 WebFlux 也能夠被運行在 Servlet 容器上(需是 Servlet 3.1+ 以上的容器),可是 WebFlux 主要仍是應用在異步非阻塞編程模型,而 Spring MVC 是同步阻塞的,若是你目前在 Spring MVC 框架中大量使用非同步方案,那麼,WebFlux 纔是你想要的,不然,使用 Spring MVC 纔是你的首選。

在微服務架構中,Spring MVC 和 WebFlux 能夠混合使用,好比已經提到的,對於那些 IO 密集型服務(如網關),咱們就可使用 WebFlux 來實現。

選 WebFlux 仍是 Spring MVC? This is not a problem!

咱不能爲了裝逼而裝逼,爲了技術而技術,還要考量到轉向非阻塞響應式編程學習曲線是陡峭的,小組成員的學習成本等諸多因素。

總之一句話,在合適的場景中,選型最合適的技術

5、異同點

WebFlux 適用性
WebFlux 適用性

從上圖中,能夠一眼看出 Spring MVC 和 Spring WebFlux 的相同點和不一樣點:

相同點:

  • 均可以使用 Spring MVC 註解,如 @Controller, 方便咱們在兩個 Web 框架中自由轉換;
  • 都可以使用 Tomcat, Jetty, Undertow Servlet 容器(Servlet 3.1+);
  • ...

注意點:

  • Spring MVC 由於是使用的同步阻塞式,更方便開發人員編寫功能代碼,Debug 測試等,通常來講,若是 Spring MVC 可以知足的場景,就儘可能不要用 WebFlux;
  • WebFlux 默認狀況下使用 Netty 做爲服務器;
  • WebFlux 不支持 MySql;

6、簡單看看 WebFlux 是如何分發請求的

使用過 Spring MVC 的小夥伴們,應該到知道 Spring MVC 的前端控制器是 DispatcherServlet, 而 WebFlux 是 DispatcherHandler,它實現了 WebHandler 接口:

WebFlux WebHandler接口
WebFlux WebHandler接口

來看看DispatcherHandler類中處理請求的 handle 方法:

WebFlux handle 源碼分析
WebFlux handle 源碼分析

  • ①:ServerWebExchange 對象中放置每一次 HTTP 請求響應信息,包括參數等;
  • ②: 判斷整個接口映射 mappings 集合是否爲空,空則建立一個 Not Found 的錯誤;
  • ③: 根據具體的請求地址獲取對應的 handlerMapping;
  • ④: 調用具體業務方法,也就是咱們定義的接口方法;
  • ⑤: 處理返回的結果;

7、快速入門

7.1 添加 webflux 依賴

新建一個 Spring Boot 項目,新建步驟可參考筆者另外一篇博文《Spring Boot 入門教程 | 圖文講解》,在 pom.xml 文件中添加 webflux 依賴:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
複製代碼

7.2 定義接口

新建一個 controller 包,用來放置對外的接口類,再建立一個 HelloWebFluxController.class 類,定義兩個接口:

package site.exception.springbootwebfluxhello.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;
import site.exception.springbootwebfluxhello.entity.User;

/** * @author 犬小哈 (微信號: 小哈學Java) * @site 我的網站: www.exception.site * @date 2019/4/15 * @time 下午9:12 * @discription **/
@RestController
public class HelloWebFluxController {

    @GetMapping("/hello")
    public String hello() {
        return "Hello, WebFlux !";
    }

    @GetMapping("/user")
    public Mono<User> getUser() {
        User user = new User();
        user.setName("犬小哈");
        user.setDesc("歡迎關注個人公衆號: 小哈學Java");
        return Mono.just(user);
    }


}

複製代碼

User.java:

package site.exception.springbootwebfluxhello.entity;

/** * @author 犬小哈 (微信號: 小哈學Java) * @site 我的網站: www.exception.site * @date 2019/4/15 * @time 下午9:12 * @discription **/
public class User {

    /** * 姓名 */
    private String name;
    /** * 描述 */
    private String desc;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }
}
複製代碼

以上控制器類中,咱們使用的全都是 Spring MVC 的註解,分別定義了兩個接口:

  • 一個 GET 請求的 /hello 接口,返回 Hello, WebFlux !字符串。
  • 又定義了一個 GET 請求的 /user方法,返回的是 JSON 格式 User 對象。

這裏注意,User 對象是經過 Mono 對象包裝的,你可能會問,爲啥不直接返回呢?

在 WebFlux 中,Mono 是非阻塞的寫法,只有這樣,你才能發揮 WebFlux 非阻塞 + 異步的特性。

補充:在 WebFlux 中,除了 Mono 外,還有一個 Flux,這哥倆均能充當響應式編程中發佈者的角色,不一樣的是:

  • Mono:返回 0 或 1 個元素,即單個對象。
  • Flux:返回 N 個元素,即 List 列表對象。

7.3 測試接口

啓動項目,查看控制檯輸出:

啓動 WebFlux 項目
啓動 WebFlux 項目

當控制檯中輸出中包含 Netty started on port(s): 8080 語句時,說明默認使用 Netty 服務已經啓動了。

打開瀏覽器,先對 /user 接口發起調用:

請求 /hello 接口
請求 /hello 接口

返回成功。

再來對 /user 接口測試一下:

請求 /user 接口
請求 /user 接口

返回 JSON 格式的 User 實體也是 OK 的!

8、總結

本文中,咱們學習了什麼是 Spring WebFlux, WebFlux 的優點和應用場景,接下來我麼談了談在咱們生產環境中技術選型該選 WebFlux 仍是 Spring MVC, 二者之間又有什麼異同點,以及從源碼角度瞭解了 WebFlux 是如何分發請求的。

最後上手操做寫了兩個簡單的接口,並測試成功了。

下一章中,咱們將進一步學習,如何在 WebFlux 中對數據庫作增刪改查操做,敬請期待吧!

9、GitHub 示例代碼

github.com/weiwosuoai/…

10、Ref

贈送 | 面試&學習福利資源

最近在網上發現一個不錯的 PDF 資源《Java 核心面試知識.pdf》分享給你們,不光是面試,學習,你都值得擁有!!!

獲取方式: 關注公衆號: 小哈學Java, 後臺回覆 資源,既可獲取資源連接,下面是目錄以及部分截圖:

福利資源截圖
福利資源截圖

福利資源截圖
福利資源截圖

福利資源截圖
福利資源截圖

福利資源截圖
福利資源截圖

福利資源截圖
福利資源截圖

福利資源截圖
福利資源截圖

福利資源截圖
福利資源截圖

重要的事情說兩遍,獲取方式: 關注公衆號: 小哈學Java, 後臺回覆 資源,既可獲取資源連接 !!!

歡迎關注微信公衆號: 小哈學Java

小哈學Java
小哈學Java
相關文章
相關標籤/搜索