天天看點

211. Spring Boot WebFlux:使用篇

211. Spring Boot WebFlux:使用篇

【視訊&交流平台】

SpringBoot視訊:http://t.cn/R3QepWG

Spring Cloud視訊:http://t.cn/R3QeRZc

SpringBoot Shiro視訊:http://t.cn/R3QDMbh

SpringBoot交流平台:http://t.cn/R3QDhU0

SpringBoot 2.0 SpringData和JPA視訊:

http://t.cn/R1pSojf

說明

(1)JDK版本:1.8

(2)Spring Boot 2.0.5

需求緣起

       在上一篇部落格中我們對于WebFlux的一些概念進行了掃清,這篇文章我們主要使用了一個簡單的例子來體驗下WebFlux的編碼方式。對于本篇的編碼是先建構一個Spring WebMVC,然後再轉換為Spring Reactive Web。

一、基于WebMVC注解的方式

1.1 建立項目

       建立一個項目,這裡取名為:springboot2-webflux。如果使用的是spring boot的自動生成代碼的方式的話,那麼下面的1.2、1.3的代碼都會自動生成的。

1.2 添加依賴

       對于Spring MVC所需要的依賴是-starter-web,如下:

<parent>

       <groupId>org.springframework.boot</groupId>

       <artifactId>spring-boot-starter-parent</artifactId>

       <version>2.0.5.RELEASE</version>

       <relativePath/>

    </parent>



    <properties>

       <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

       <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

       <java.version>1.8</java.version>

    </properties>



    <dependencies>

       <dependency>

           <groupId>org.springframework.boot</groupId>

           <artifactId>spring-boot-starter-web</artifactId>

       </dependency>



    </dependencies>
           

1.3 添加啟動類

       建構啟動類

@SpringBootApplication

publicclassSpringboot2WebfluxApplication {



    publicstaticvoid main(String[] args) {

       SpringApplication.run(Springboot2WebfluxApplication.class, args);

    }

}
           

1.4 添加controller

       添加一個PersonController:

@RestController

publicclass PersonController{



    @GetMapping("/hello")

    public String hello() {

       return"Welcome to reactive world";

    }

}
           

1.5 啟動測試

       啟動Spring Boot應用進行測試,通路如下位址:

http://127.0.0.1:8080/hello

二、改造為WebFlux的項目

2.1 修改依賴的stater

       修改原先依賴的-web為-webflux:

<dependency>

           <groupId>org.springframework.boot</groupId>

           <artifactId>spring-boot-starter-webflux</artifactId>

       </dependency>
           

2.2 修改Controller

       修改PersonController中處理請求的傳回類型采用響應式類型:

@RestController

publicclass PersonController{



    @GetMapping("/hello")

    public Mono<String>hello() {//【改】傳回類型為Mono<String>

       return Mono.just("Welcome to reactive world"); // 【改】使用Mono.just生成響應式資料

    }

}
           

2.3 啟動應用

       啟動應用,通路http://localhost:8080/hello,結果與Spring WebMVC的相同。

2.4 總結

從上邊這個簡單的例子中可以看出, WebFlux提供了與之前WebMVC相同的一套注解來定義請求的處理,使得Spring使用者遷移到響應式開發方式的過程變得異常輕松。

雖然我們隻修改了少量的代碼,整個技術棧從指令式的、同步阻塞的【spring-webmvc+ servlet + Tomcat】變成了響應式的、異步非阻塞的【spring-webflux + Reactor + Netty】。

三、WebFlux的函數式開發模式

既然是響應式程式設計了,有些朋友可能會想統一用函數式的程式設計風格,WebFlux滿足你。WebFlux提供了一套函數式接口,可以用來實作類似MVC的效果

       我們對于Controller的定義,主要是兩點:

(1)方法定義處理邏輯:如hello()方法;

(2)使用@RequestMapping注解定義好這個方法對什麼樣url進行相應:如@GetMapping("/hello")

       在WebFlux的函數開發模式中,使用HandlerFunction和RouterFunction來實作上面的這兩點。

(1)HandlerFunction相當于Controller中的具體處理方法,輸入為請求,輸出為裝在Mono中的響應。

(2)RouterFunction,路由,相當于@RequestMapping,用來判斷什麼樣的url映射到那個具體的HandlerFunction,輸入為請求,輸出為裝在Mono裡面的HandlerFunction。

3.1 開發步驟一:編寫處理器類Handler

       建立包 com.kfit.webflux.handler,作為編寫功能處理類。

@Component

publicclass PersonHandler {



    public Mono<ServerResponse>helloPerson(ServerRequest request) {

       return ServerResponse.ok().contentType(MediaType.TEXT_PLAIN).body(BodyInserters.fromObject("Hello, Person!"));

    }



}
           

ServerResponse 是對響應的封裝,可以設定響應狀态,響應頭,響應正文。比如 ok 代表的是 200 響應碼、MediaType枚舉是代表這文本内容類型、傳回的是 String 的對象。

3.2 開發步驟二:編寫路由器類 Router

建立 com.kfit.webflux.router 包,作為編寫路由器類:

package com.kfit.webflux.router;



importorg.springframework.context.annotation.Bean;

importorg.springframework.context.annotation.Configuration;

importorg.springframework.http.MediaType;

importorg.springframework.web.reactive.function.server.RequestPredicates;

importorg.springframework.web.reactive.function.server.RouterFunction;

importorg.springframework.web.reactive.function.server.RouterFunctions;

import org.springframework.web.reactive.function.server.ServerResponse;



importcom.kfit.webflux.handler.PersonHandler;



@Configuration

publicclass PersonRouter {



     @Bean

     public RouterFunction<ServerResponse>routeCity(PersonHandler personHandler) {

            return RouterFunctions

                    .route(RequestPredicates.GET("/helloPerson")

                .and(RequestPredicates.accept(MediaType.TEXT_PLAIN)),personHandler::helloPerson);

        }



}
           

RouterFunctions對請求路由處理類,即将請求路由到處理器。這裡将一個 GET 請求 /hello 路由到處理器 cityHandler 的 helloCity 方法上。跟 Spring MVC 模式下的 HandleMapping 的作用類似。

3.3 運作測試