Spring Boot 2 快速教程:WebFlux 快速入門(二)

摘要: 原創(chuàng)出處 https://www.bysocket.com 「公眾號(hào):泥瓦匠BYSocket 」歡迎關(guān)注和轉(zhuǎn)載码耐,保留摘要疟呐,謝謝计济!

02:WebFlux 快速入門實(shí)踐

文章工程:

  • JDK 1.8
  • Maven 3.5.2
  • Spring Boot 2.1.3.RELEASE
  • 工程名:springboot-webflux-1-quickstart
  • 工程地址:見文末

一园细、Spring Boot 2.0

spring.io 官網(wǎng)有句醒目的話是:

BUILD ANYTHING WITH SPRING BOOT

Spring Boot (Boot 顧名思義唆垃,是引導(dǎo)的意思)框架是用于簡(jiǎn)化 Spring 應(yīng)用從搭建到開發(fā)的過程。應(yīng)用開箱即用趁猴,只要通過一個(gè)指令刊咳,包括命令行 java -jarSpringApplication 應(yīng)用啟動(dòng)類 儡司、 Spring Boot Maven 插件等娱挨,就可以啟動(dòng)應(yīng)用了。另外捕犬,Spring Boot 強(qiáng)調(diào)只需要很少的配置文件跷坝,所以在開發(fā)生產(chǎn)級(jí) Spring 應(yīng)用中,讓開發(fā)變得更加高效和簡(jiǎn)易碉碉。目前柴钻,Spring Boot 版本是 2.x 版本。Spring Boot 包括 WebFlux垢粮。

image

二贴届、Spring Boot 2.0 WebFlux

了解 WebFlux ,首先了解下什么是 Reactive Streams。Reactive Streams 是 JVM 中面向流的庫(kù)標(biāo)準(zhǔn)和規(guī)范:

  • 處理可能無限數(shù)量的元素
  • 按順序處理
  • 組件之間異步傳遞
  • 強(qiáng)制性非阻塞背壓(Backpressure)

2.1 Backpressure(背壓)

背壓是一種常用策略蜡吧,使得發(fā)布者擁有無限制的緩沖區(qū)存儲(chǔ)元素毫蚓,用于確保發(fā)布者發(fā)布元素太快時(shí),不會(huì)去壓制訂閱者昔善。

2.2 Reactive Streams(響應(yīng)式流)

一般由以下組成:

  • 發(fā)布者:發(fā)布元素到訂閱者
  • 訂閱者:消費(fèi)元素
  • 訂閱:在發(fā)布者中元潘,訂閱被創(chuàng)建時(shí),將與訂閱者共享
  • 處理器:發(fā)布者與訂閱者之間處理數(shù)據(jù)

2.3 響應(yīng)式編程
有了 Reactive Streams 這種標(biāo)準(zhǔn)和規(guī)范君仆,利用規(guī)范可以進(jìn)行響應(yīng)式編程柬批。那再了解下什么是 Reactive programming 響應(yīng)式編程啸澡。響應(yīng)式編程是基于異步和事件驅(qū)動(dòng)的非阻塞程序,只是垂直通過在 JVM 內(nèi)啟動(dòng)少量線程擴(kuò)展氮帐,而不是水平通過集群擴(kuò)展嗅虏。這就是一個(gè)編程范例,具體項(xiàng)目中如何體現(xiàn)呢上沐?

響應(yīng)式項(xiàng)目編程實(shí)戰(zhàn)中皮服,通過基于 Reactive Streams 規(guī)范實(shí)現(xiàn)的框架 Reactor 去實(shí)戰(zhàn)。Reactor 一般提供兩種響應(yīng)式 API :

  • Mono:實(shí)現(xiàn)發(fā)布者参咙,并返回 0 或 1 個(gè)元素
  • Flux:實(shí)現(xiàn)發(fā)布者龄广,并返回 N 個(gè)元素

2.4 Spring Webflux

Spring Boot Webflux 就是基于 Reactor 實(shí)現(xiàn)的。Spring Boot 2.0 包括一個(gè)新的 spring-webflux 模塊蕴侧。該模塊包含對(duì)響應(yīng)式 HTTP 和 WebSocket 客戶端的支持择同,以及對(duì) REST,HTML 和 WebSocket 交互等程序的支持净宵。一般來說敲才,Spring MVC 用于同步處理,Spring Webflux 用于異步處理择葡。

Spring Boot Webflux 有兩種編程模型實(shí)現(xiàn)紧武,一種類似 Spring MVC 注解方式,另一種是使用其功能性端點(diǎn)方式敏储。注解的會(huì)在第二篇文章講到阻星,下面快速入門用 Spring Webflux 功能性方式實(shí)現(xiàn)。

三已添、Spring Boot 2.0 WebFlux 特性

常用的 Spring Boot 2.0 WebFlux 生產(chǎn)的特性如下:

  • 響應(yīng)式 API
  • 編程模型
  • 適用性
  • 內(nèi)嵌容器
  • Starter 組件

還有對(duì)日志妥箕、Web、消息更舞、測(cè)試及擴(kuò)展等支持畦幢。

3.1 響應(yīng)式 API

Reactor 框架是 Spring Boot Webflux 響應(yīng)庫(kù)依賴,通過 Reactive Streams 并與其他響應(yīng)庫(kù)交互疏哗。提供了 兩種響應(yīng)式 API : Mono 和 Flux。一般是將 Publisher 作為輸入禾怠,在框架內(nèi)部轉(zhuǎn)換成 Reactor 類型并處理邏輯返奉,然后返回 Flux 或 Mono 作為輸出。

3.2 適用性

[圖片上傳失敗...(image-bb652e-1557336397645)]

一圖就很明確了吗氏,WebFlux 和 MVC 有交集芽偏,方便大家遷移。但是注意:

  • MVC 能滿足場(chǎng)景的弦讽,就不需要更改為 WebFlux污尉。
  • 要注意容器的支持膀哲,可以看看下面內(nèi)嵌容器的支持。
  • 微服務(wù)體系結(jié)構(gòu)被碗,WebFlux 和 MVC 可以混合使用某宪。尤其開發(fā) IO 密集型服務(wù)的時(shí)候,選擇 WebFlux 去實(shí)現(xiàn)馁蒂。

3.3 編程模型

Spring 5 web 模塊包含了 Spring WebFlux 的 HTTP 抽象淹办。類似 Servlet API , WebFlux 提供了 WebHandler API 去定義非阻塞 API 抽象接口肛走。可以選擇以下兩種編程模型實(shí)現(xiàn):

  • 注解控制層衣迷。和 MVC 保持一致,WebFlux 也支持響應(yīng)性 @RequestBody 注解酱酬。
  • 功能性端點(diǎn)壶谒。基于 lambda 輕量級(jí)編程模型膳沽,用來路由和處理請(qǐng)求的小工具汗菜。和上面最大的區(qū)別就是,這種模型贵少,全程控制了請(qǐng)求 - 響應(yīng)的生命流程

3.4 內(nèi)嵌容器

跟 Spring Boot 大框架一樣啟動(dòng)應(yīng)用呵俏,但 WebFlux 默認(rèn)是通過 Netty 啟動(dòng),并且自動(dòng)設(shè)置了默認(rèn)端口為 8080滔灶。另外還提供了對(duì) Jetty普碎、Undertow 等容器的支持。開發(fā)者自行在添加對(duì)應(yīng)的容器 Starter 組件依賴录平,即可配置并使用對(duì)應(yīng)內(nèi)嵌容器實(shí)例麻车。

但是要注意,必須是 Servlet 3.1+ 容器斗这,如 Tomcat动猬、Jetty;或者非 Servlet 容器表箭,如 Netty 和 Undertow赁咙。

3.5 Starter 組件

跟 Spring Boot 大框架一樣,Spring Boot Webflux 提供了很多 “開箱即用” 的 Starter 組件免钻。Starter 組件是可被加載在應(yīng)用中的 Maven 依賴項(xiàng)彼水。只需要在 Maven 配置中添加對(duì)應(yīng)的依賴配置,即可使用對(duì)應(yīng)的 Starter 組件极舔。例如凤覆,添加 spring-boot-starter-webflux 依賴,就可用于構(gòu)建響應(yīng)式 API 服務(wù)拆魏,其包含了 Web Flux 和 Tomcat 內(nèi)嵌容器等盯桦。

開發(fā)中慈俯,很多功能是通過添加 Starter 組件的方式來進(jìn)行實(shí)現(xiàn)。那么拥峦,Spring Boot 2.x 常用的 Starter 組件有哪些呢贴膘?

四、Spring Boot 2.0 WebFlux 組件

Spring Boot WebFlux 官方提供了很多 Starter 組件事镣,每個(gè)模塊會(huì)有多種技術(shù)實(shí)現(xiàn)選型支持步鉴,來實(shí)現(xiàn)各種復(fù)雜的業(yè)務(wù)需求:

  • Web:Spring WebFlux
  • 模板引擎:Thymeleaf
  • 存儲(chǔ):Redis、MongoDB璃哟、Cassandra氛琢。不支持 MySQL
  • 內(nèi)嵌容器:Tomcat、Jetty随闪、Undertow

五阳似、快速入門

5.1 Spring Initializr 快速構(gòu)建項(xiàng)目骨架

Spring Boot Maven 工程,就是普通的 Maven 工程铐伴,加入了對(duì)應(yīng)的 Spring Boot 依賴即可撮奏。Spring Initializr 則是像代碼生成器一樣,自動(dòng)就給你出來了一個(gè) Spring Boot Maven 工程当宴。Spring Initializr 有兩種方式可以得到 Spring Boot Maven 骨架工程:

5.1.1 start.spring.io 在線生成

Spring 官方提供了名為 Spring Initializr 的網(wǎng)站畜吊,去引導(dǎo)你快速生成 Spring Boot 應(yīng)用。網(wǎng)站地址為:https://start.spring.io户矢,操作步驟如下:

第一步玲献,選擇 Maven 或者 Gradle 構(gòu)建工具,開發(fā)語言 Java 梯浪、Kotlin 或者 Groovy捌年,最后確定 Spring Boot 版本號(hào)。這里默認(rèn)選擇 Maven 構(gòu)建工具挂洛、Java 開發(fā)語言和 Spring Boot 2.0.1礼预。

第二步,輸入 Maven 工程信息虏劲,即項(xiàng)目組 groupId 和名字 artifactId托酸。這里對(duì)應(yīng) Maven 信息為:

  • groupId:springboot
  • artifactId:sspringboot-webflux-1-quickstart
    這里默認(rèn)版本號(hào) version 為 0.0.1-SNAPSHOT 。三個(gè)屬性在 Maven 依賴倉(cāng)庫(kù)是唯一標(biāo)識(shí)的柒巫。

第三步励堡,選擇工程需要的 Starter 組件和其他依賴。最后點(diǎn)擊生成按鈕吻育,即可獲得骨架工程壓縮包念秧。這里快速入門淤井,只要選擇 Reactive Web 即可布疼。如圖 1-8 所示摊趾。

[圖片上傳失敗...(image-71c0ee-1557336397645)]

5.2 配置 POM 依賴

檢查工程 POM 文件中,是否配置了 spring-boot-starter-webflux 依賴游两。如果是上面自動(dòng)生成的砾层,配置如下:

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

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>io.projectreactor</groupId>
      <artifactId>reactor-test</artifactId>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>

spring-boot-starter-webflux 依賴,是我們核心需要學(xué)習(xí) webflux 的包贱案,里面默認(rèn)包含了 spring-boot-starter-reactor-netty 肛炮、spring 5 webflux 包。也就是說默認(rèn)是通過 netty 啟動(dòng)的宝踪。

reactor-test侨糟、spring-boot-starter-test 兩個(gè)依賴搭配是用于單元測(cè)試。

spring-boot-maven-plugin 是 Spring Boot Maven 插件瘩燥,可以運(yùn)行秕重、編譯等調(diào)用。

5.3 編寫處理器類 Handler

新建包 org.spring.springboot.handler 厉膀,作為編寫功能處理類溶耘。新建城市(City)例子的處理類 CityHandler,代碼如下:

import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono;

@Component
public class CityHandler {

    public Mono<ServerResponse> helloCity(ServerRequest request) {
        return ServerResponse.ok().contentType(MediaType.TEXT_PLAIN)
                .body(BodyInserters.fromObject("Hello, City!"));
    }
}

ServerResponse 是對(duì)響應(yīng)的封裝服鹅,可以設(shè)置響應(yīng)狀態(tài)凳兵,響應(yīng)頭,響應(yīng)正文企软。比如 ok 代表的是 200 響應(yīng)碼庐扫、MediaType 枚舉是代表這文本內(nèi)容類型、返回的是 String 的對(duì)象澜倦。

這里用 Mono 作為返回對(duì)象聚蝶,是因?yàn)榉祷匕艘粋€(gè) ServerResponse 對(duì)象,而不是多個(gè)元素藻治。

5.4 編寫路由器類 Router

新建 org.spring.springboot.router 包碘勉,作為編寫路由器類。新建城市(City)例子的路由類 CityRouter桩卵,代碼如下:

import org.spring.springboot.handler.CityHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.server.RequestPredicates;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.reactive.function.server.ServerResponse;

@Configuration
public class CityRouter {


    @Bean
    public RouterFunction<ServerResponse> routeCity(CityHandler cityHandler) {
        return RouterFunctions
                .route(RequestPredicates.GET("/hello")
                                .and(RequestPredicates.accept(MediaType.TEXT_PLAIN)),
                        cityHandler::helloCity);
    }

}

RouterFunctions 對(duì)請(qǐng)求路由處理類验靡,即將請(qǐng)求路由到處理器。這里將一個(gè) GET 請(qǐng)求 /hello 路由到處理器 cityHandler 的 helloCity 方法上雏节。跟 Spring MVC 模式下的 HandleMapping 的作用類似胜嗓。

RouterFunctions.route(RequestPredicate, HandlerFunction) 方法,對(duì)應(yīng)的入?yún)⑹钦?qǐng)求參數(shù)和處理函數(shù)钩乍,如果請(qǐng)求匹配辞州,就調(diào)用對(duì)應(yīng)的處理器函數(shù)。

到這里一個(gè)簡(jiǎn)單的服務(wù)就寫好了寥粹,下面怎么運(yùn)行該服務(wù)变过。

5.5 啟動(dòng)運(yùn)行項(xiàng)目

一個(gè)簡(jiǎn)單的 Spring Boot Webflux 工程就開發(fā)完畢了埃元,下面運(yùn)行工程驗(yàn)證下。使用 IDEA 右側(cè)工具欄媚狰,點(diǎn)擊 Maven Project Tab 岛杀,點(diǎn)擊使用下 Maven 插件的 install 命令≌腹拢或者使用命令行的形式类嗤,在工程根目錄下,執(zhí)行 Maven 清理和安裝工程的指令:

cd springboot-webflux-1-quickstart
mvn clean install

在控制臺(tái)中看到成功的輸出:

... 省略
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 01:30 min
[INFO] Finished at: 2017-10-15T10:00:54+08:00
[INFO] Final Memory: 31M/174M
[INFO] ------------------------------------------------------------------------

5.5.1 運(yùn)行工程

在 IDEA 中執(zhí)行 Application 類啟動(dòng)辨宠,任意正常模式或者 Debug 模式遗锣。可以在控制臺(tái)看到成功運(yùn)行的輸出:

... 省略
2018-04-10 08:43:39.932  INFO 2052 --- [ctor-http-nio-1] r.ipc.netty.tcp.BlockingNettyContext     : Started HttpServer on /0:0:0:0:0:0:0:0:8080
2018-04-10 08:43:39.935  INFO 2052 --- [           main] o.s.b.web.embedded.netty.NettyWebServer  : Netty started on port(s): 8080
2018-04-10 08:43:39.960  INFO 2052 --- [           main] org.spring.springboot.Application        : Started Application in 6.547 seconds (JVM running for 9.851)

一看嗤形,確實(shí)是 Netty 啟動(dòng)的黄伊。

打開瀏覽器,訪問 /hello 地址派殷,會(huì)看到如圖所示的返回結(jié)果:

[圖片上傳失敗...(image-91e00e-1557336397645)]

六还最、總結(jié)

本文主要講了 Spring Boot 2.0 WebFlux 背景和快速入門使用。用的是基于功能性端點(diǎn)去創(chuàng)建一個(gè)服務(wù)毡惜,但這個(gè)有點(diǎn)代碼偏多拓轻。下一章一個(gè) CRUD 我們使用注解控制層,讓開發(fā)更方便经伙。

系列教程目錄

  • 《01:WebFlux 系列教程大綱》
  • 《02:WebFlux 快速入門實(shí)踐》
  • 《03:WebFlux Web CRUD 實(shí)踐》
  • 《04:WebFlux 整合 Mongodb》
  • 《05:WebFlux 整合 Thymeleaf》
  • 《06:WebFlux 中 Thymeleaf 和 Mongodb 實(shí)踐》
  • 《07:WebFlux 整合 Redis》
  • 《08:WebFlux 中 Redis 實(shí)現(xiàn)緩存》
  • 《09:WebFlux 中 WebSocket 實(shí)現(xiàn)通信》
  • 《10:WebFlux 集成測(cè)試及部署》
  • 《11:WebFlux 實(shí)戰(zhàn)圖書管理系統(tǒng)》

代碼示例

本文示例讀者可以通過查看下面?zhèn)}庫(kù)的中的模塊工程名: 2-x-spring-boot-webflux-handling-errors:

如果您對(duì)這些感興趣扶叉,歡迎 star、follow帕膜、收藏枣氧、轉(zhuǎn)發(fā)給予支持!

參考資料

以下專題教程也許您會(huì)有興趣

(關(guān)注微信公眾號(hào)垮刹,領(lǐng)取 Java 精選干貨學(xué)習(xí)資料)
(添加我微信:bysocket01达吞。加入純技術(shù)交流群,成長(zhǎng)技術(shù))

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末荒典,一起剝皮案震驚了整個(gè)濱河市酪劫,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌寺董,老刑警劉巖覆糟,帶你破解...
    沈念sama閱讀 206,311評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異遮咖,居然都是意外死亡滩字,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來麦箍,“玉大人酗电,你說我怎么就攤上這事∧诹校” “怎么了?”我有些...
    開封第一講書人閱讀 152,671評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵背率,是天一觀的道長(zhǎng)话瞧。 經(jīng)常有香客問我,道長(zhǎng)寝姿,這世上最難降的妖魔是什么交排? 我笑而不...
    開封第一講書人閱讀 55,252評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮饵筑,結(jié)果婚禮上埃篓,老公的妹妹穿的比我還像新娘。我一直安慰自己根资,他們只是感情好架专,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評(píng)論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著玄帕,像睡著了一般部脚。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上裤纹,一...
    開封第一講書人閱讀 49,031評(píng)論 1 285
  • 那天委刘,我揣著相機(jī)與錄音,去河邊找鬼鹰椒。 笑死锡移,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的漆际。 我是一名探鬼主播淆珊,決...
    沈念sama閱讀 38,340評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼奸汇!你這毒婦竟也來了套蒂?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,973評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤茫蛹,失蹤者是張志新(化名)和其女友劉穎操刀,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體婴洼,經(jīng)...
    沈念sama閱讀 43,466評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡骨坑,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片欢唾。...
    茶點(diǎn)故事閱讀 38,039評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡且警,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出礁遣,到底是詐尸還是另有隱情斑芜,我是刑警寧澤,帶...
    沈念sama閱讀 33,701評(píng)論 4 323
  • 正文 年R本政府宣布祟霍,位于F島的核電站杏头,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏沸呐。R本人自食惡果不足惜醇王,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望崭添。 院中可真熱鬧寓娩,春花似錦、人聲如沸呼渣。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)屁置。三九已至排嫌,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間缰犁,已是汗流浹背淳地。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留帅容,地道東北人颇象。 一個(gè)月前我還...
    沈念sama閱讀 45,497評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像并徘,于是被迫代替她去往敵國(guó)和親遣钳。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容