Spring Boot WebFlux-01——WebFlux 快速入門實踐

第01課:WebFlux 快速入門實踐

Spring Boot 2.0

spring.io 官網有句醒目的話是:java

BUILD ANYTHING WITH SPRING BOOT 

Spring Boot (Boot 顧名思義,是引導的意思)框架是用於簡化 Spring 應用從搭建到開發的過程。應用開箱即用,只要經過一個指令,包括命令行 java -jarSpringApplication 應用啓動類 、 Spring Boot Maven 插件等,就能夠啓動應用了。另外,Spring Boot 強調只須要不多的配置文件,因此在開發生產級 Spring 應用中,讓開發變得更加高效和簡易。目前,Spring Boot 版本是 2.x 版本。Spring Boot 包括 WebFlux。react

Spring Boot 2.0 WebFlux

瞭解 WebFlux,首先了解下什麼是 Reactive Streams。Reactive Streams 是 JVM 中面向流的庫標準和規範:nginx

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

Backpressure(背壓)web

背壓是一種經常使用策略,使得發佈者擁有無限制的緩衝區存儲元素,用於確保發佈者發佈元素太快時,不會去壓制訂閱者。spring

Reactive Streams(響應式流)sql

通常由如下組成:編程

  • 發佈者:發佈元素到訂閱者
  • 訂閱者:消費元素
  • 訂閱:在發佈者中,訂閱被建立時,將與訂閱者共享
  • 處理器:發佈者與訂閱者之間處理數據

響應式編程瀏覽器

有了 Reactive Streams 這種標準和規範,利用規範能夠進行響應式編程。那再瞭解下什麼是 Reactive programming 響應式編程。響應式編程是基於異步和事件驅動的非阻塞程序,只是垂直經過在 JVM 內啓動少許線程擴展,而不是水平經過集羣擴展。這就是一個編程範例,具體項目中如何體現呢?springboot

響應式項目編程實戰中,經過基於 Reactive Streams 規範實現的框架 Reactor 去實戰。Reactor 通常提供兩種響應式 API :bash

  • Mono:實現發佈者,並返回 0 或 1 個元素
  • Flux:實現發佈者,並返回 N 個元素

Spring Webflux

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

Spring Boot Webflux 有兩種編程模型實現,一種相似 Spring MVC 註解方式,另外一種是使用其功能性端點方式。註解的會在第二篇文章講到,下面快速入門用 Spring Webflux 功能性方式實現。

Spring Boot 2.0 WebFlux 特性

經常使用的 Spring Boot 2.0 WebFlux 生產的特性以下:

  • 響應式 API
  • 編程模型
  • 適用性
  • 內嵌容器
  • Starter 組件

還有對日誌、Web、消息、測試及擴展等支持。

響應式 API

Reactor 框架是 Spring Boot Webflux 響應庫依賴,經過 Reactive Streams 並與其餘響應庫交互。提供了 兩種響應式 API:Mono 和 Flux。通常是將 Publisher 做爲輸入,在框架內部轉換成 Reactor 類型並處理邏輯,而後返回 Flux 或 Mono 做爲輸出。

適用性

file

一圖就很明確了,WebFlux 和 MVC 有交集,方便你們遷移。可是注意:

  • MVC 能知足場景的,就不須要更改成 WebFlux。
  • 要注意容器的支持,能夠看看下面內嵌容器的支持。
  • 微服務體系結構,WebFlux 和 MVC 能夠混合使用。尤爲開發 IO 密集型服務的時候,選擇 WebFlux 去實現。

編程模型

Spring 5 web 模塊包含了 Spring WebFlux 的 HTTP 抽象。相似 Servlet API , WebFlux 提供了 WebHandler API 去定義非阻塞 API 抽象接口。能夠選擇如下兩種編程模型實現:

  • 註解控制層。和 MVC 保持一致,WebFlux 也支持響應性 @RequestBody 註解。
  • 功能性端點。基於 lambda 輕量級編程模型,用來路由和處理請求的小工具。和上面最大的區別就是,這種模型,全程控制了請求 - 響應的生命流程

內嵌容器

跟 Spring Boot 大框架同樣啓動應用,但 WebFlux 默認是經過 Netty 啓動,而且自動設置了默認端口爲 8080。另外還提供了對 Jetty、Undertow 等容器的支持。開發者自行在添加對應的容器 Starter 組件依賴,便可配置並使用對應內嵌容器實例。

可是要注意,必須是 Servlet 3.1+ 容器,如 Tomcat、Jetty;或者非 Servlet 容器,如 Netty 和 Undertow。

Starter 組件

跟 Spring Boot 大框架同樣,Spring Boot Webflux 提供了不少 「開箱即用」 的 Starter 組件。Starter 組件是可被加載在應用中的 Maven 依賴項。只須要在 Maven 配置中添加對應的依賴配置,便可使用對應的 Starter 組件。例如,添加 spring-boot-starter-webflux 依賴,就可用於構建響應式 API 服務,其包含了 Web Flux 和 Tomcat 內嵌容器等。

開發中,不少功能是經過添加 Starter 組件的方式來進行實現。那麼,Spring Boot 2.x 經常使用的 Starter 組件有哪些呢?

Spring Boot 2.0 WebFlux 組件

Spring Boot WebFlux 官方提供了不少 Starter 組件,每一個模塊會有多種技術實現選型支持,來實現各類複雜的業務需求:

  • Web:Spring WebFlux
  • 模板引擎:Thymeleaf
  • 存儲:Redis、MongoDB、Cassandra,不支持 MySQL
  • 內嵌容器:Tomcat、Jetty、Undertow

Spring Initializr 快速構建項目骨架

Spring Boot Maven 工程,就是普通的 Maven 工程,加入了對應的 Spring Boot 依賴便可。Spring Initializr 則是像代碼生成器同樣,自動就給你出來了一個 Spring Boot Maven 工程。Spring Initializr 有兩種方式能夠獲得 Spring Boot Maven 骨架工程:

start.spring.io 在線生成

Spring 官方提供了名爲 Spring Initializr 的網站,去引導你快速生成 Spring Boot 應用。網站地址,詳見這裏,操做步驟以下:

第一步,選擇 Maven 或者 Gradle 構建工具,開發語言 Java 、Kotlin 或者 Groovy,最後肯定 Spring Boot 版本號。這裏默認選擇 Maven 構建工具、Java 開發語言和 Spring Boot 2.0.1。

第二步,輸入 Maven 工程信息,即項目組 groupId 和名字 artifactId,這裏對應 Maven 信息爲:

  • groupId:springboot
  • artifactId:sspringboot-webflux-1-quickstart

這裏默認版本號 version 爲 0.0.1-SNAPSHOT,三個屬性在 Maven 依賴倉庫是惟一標識的。

第三步,選擇工程須要的 Starter 組件和其餘依賴,最後單擊「生成」按鈕,便可得到骨架工程壓縮包,這裏快速入門,只要選擇 Reactive Web 便可,如圖所示。

配置 POM 依賴

檢查工程 POM 文件中,是否配置了 spring-boot-starter-webflux 依賴。若是是上面自動生成的,配置以下:

<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 依賴,是咱們核心須要學習 webflux 的包,裏面默認包含了 spring-boot-starter-reactor-netty 、spring 5 webflux 包,也就是說默認是經過 netty 啓動的。

reactor-test、spring-boot-starter-test 兩個依賴搭配是用於單元測試。

spring-boot-maven-plugin 是 Spring Boot Maven 插件,能夠運行、編譯等調用。

編寫處理器類 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 是對響應的封裝,能夠設置響應狀態、響應頭、響應正文。好比 ok 表明的是 200 響應碼、MediaType 枚舉是表明這文本內容類型、返回的是 String 的對象。

這裏用 Mono 做爲返回對象,是由於返回包含了一個 ServerResponse 對象,而不是多個元素。

編寫路由器類 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 對請求路由處理類,即將請求路由處處理器,這裏將一個 GET 請求 /hello 路由處處理器 cityHandler 的 helloCity 方法上。跟 Spring MVC 模式下的 HandleMapping 的做用相似。

RouterFunctions.route(RequestPredicate, HandlerFunction) 方法,對應的入參是請求參數和處理函數,若是請求匹配,就調用對應的處理器函數。

到這裏一個簡單的服務就寫好了,下面怎麼運行該服務。

啓動運行項目

一個簡單的 Spring Boot Webflux 工程就開發完畢了,下面運行工程驗證下。使用 IDEA 右側工具欄,點擊 Maven Project Tab ,點擊使用下 Maven 插件的 install 命令,或者使用命令行的形式,在工程根目錄下,執行 Maven 清理和安裝工程的指令:

cd springboot-webflux-1-quickstart mvn clean install 

在控制檯中看到成功的輸出:

... 省略
[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] ------------------------------------------------------------------------ 

運行工程

在 IDEA 中執行 Application 類啓動,任意正常模式或者 Debug 模式,能夠在控制檯看到成功運行的輸出:

... 省略
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) 

一看,確實是 Netty 啓動的。

打開瀏覽器,訪問 /hello 地址,會看到如圖所示的返回結果:

file

總結

本文主要講了 Spring Boot 2.0 WebFlux 背景和快速入門使用,用的是基於功能性端點去建立一個服務,但這個有點代碼偏多。下一課一個 CRUD 咱們使用註解控制層,讓開發更方便。

相關文章
相關標籤/搜索