天天看点

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 运行测试