36

【WEB系列】WebFlux之初体验

 4 years ago
source link: http://spring.hhui.top/spring-blog/2020/04/21/200421-SpringBoot系列教程WebFlux之初体验/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Spring5就引入了Webflux,基于响应式编程的web框架,号称相比较于传统的SpringMVC性能更加(当然我也没测过,官方以及很多用过的小伙伴都持有这个观点),近年来响应式编程越来越主流了,作为一个紧跟时代潮流的小伙,有必要深入学习一下了

本篇作为Webflux系列教程的开篇,一个hello world的体验版

I. 环境

选择 SpringBoot 2.2.1.RELEASE 来搭建项目环境

pom依赖

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.1.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</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-webflux</artifactId>
    </dependency>
</dependencies>

<build>
    <pluginManagement>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </pluginManagement>
</build>
<repositories>
    <repository>
        <id>spring-snapshots</id>
        <name>Spring Snapshots</name>
        <url>https://repo.spring.io/libs-snapshot-local</url>
        <snapshots>
            <enabled>true</enabled>
        </snapshots>
    </repository>
    <repository>
        <id>spring-milestones</id>
        <name>Spring Milestones</name>
        <url>https://repo.spring.io/libs-milestone-local</url>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
    </repository>
    <repository>
        <id>spring-releases</id>
        <name>Spring Releases</name>
        <url>https://repo.spring.io/libs-release-local</url>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
    </repository>
</repositories>

webflux默认开启的端口号也是8080, 如果需要修改,和SpringMVC的配置一样,如修改配置文件 application.yml

server:
  port: 8080

II. WebFlux体验

使用WebFlux来提供http服务,如果是熟悉SpringMVC这一套玩法的话,基本上只要一点点改动即可

1. SpringMVC写法

借助 @Controller , @RequestMapping 注解来实现rest接口

@RestController
@RequestMapping(path = "base")
public class BasicAction {

    @GetMapping(path = "hello")
    public Mono<String> sayHello(@RequestParam("name") String name) {
        return Mono.just("hello " + name);
    }


    @GetMapping(path = "loop")
    public Flux<ServerSentEvent<String>> everySayHello(@RequestParam("name") String name) {
        return Flux.interval(Duration.ofSeconds(1)).map(seed -> seed + seed)
                .map(s -> ServerSentEvent.<String>builder().event("rand").data(name + "|" + s).build());
    }

}

上面提供了两个接口,请注意返回值

Mono<String>
Flux<ServerSentEvent<String>>

其次对于第二个接口 everySayHello ,它实现了SSE的功能,每1s往客户端推送一个字符串

关于sse,推荐查看 【WEB系列】异步请求知识点与使用姿势小结 了解基本知识点;查看 【WEB系列】SSE服务器发送事件详解 查看SpringMVC的用法,两相对比获取更好的体验

接下来演示一下测试结果

aEVbeye.gif

2. 函数开发模式

除了上面的写法之外,Webflux还可以通过配置Router来指定url与function之间的匹配关系,在这种写法中,我们常用的Controller被称为Handler;使用 RouterFunction 配置路由

重写一下上面的两个功能

@Component
public class ShowAction {

    public Mono<ServerResponse> hello(ServerRequest serverRequest) {
        return ServerResponse.ok().contentType(MediaType.TEXT_PLAIN)
                .body(Mono.just("hello " + serverRequest.queryParam("name").orElse("NoBody")), String.class);
    }
 
    /**
     * sse 服务端推送模式, 每隔一秒向客户端推送一次数据
     *
     * @param serverRequest
     * @return
     */
    public Mono<ServerResponse> sendTimePerSec(ServerRequest serverRequest) {
        return ok().contentType(MediaType.TEXT_EVENT_STREAM).body(Flux.interval(Duration.ofSeconds(1))
                .map(l -> new SimpleDateFormat("HH:mm:ss").format(new Date())), String.class);
    }
}

请注意,上面的写法并没有表明什么url匹配这个方法,所以我们需要额外的配置

@Configuration
public class RouterConfig {
    @Autowired
    private ShowAction showAction;

    @Bean
    public RouterFunction<ServerResponse> timerRouter() {
        return RouterFunctions
                .route(RequestPredicates.GET("/hello"), showAction::hello)
                .andRoute(RequestPredicates.GET("/times"), showAction::sendTimePerSec);
    }
}

再次测试

yMJ7ja6.gif

3. 小结

本文主要属于 webfluxhello world 篇,主要目的就是先对这个有一点熟悉和了解,函数式编程模式和我们一把的开发方式还是有一些区别的,这些会在后续的系列教程中逐步展开

下一篇将主要介绍WebFlux中的两个重要的类 Mono , Flux 是什么,怎么用(恳请持续关注:blush::blush::blush:)

II. 其他

0. 项目

1. 一灰灰Blog

尽信书则不如,以上内容,纯属一家之言,因个人能力有限,难免有疏漏和错误之处,如发现bug或者有更好的建议,欢迎批评指正,不吝感激

下面一灰灰的个人博客,记录所有学习和工作中的博文,欢迎大家前去逛逛

ri6Vj2M.png!web

打赏 如果觉得我的文章对您有帮助,请随意打赏。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK