快速上手WebFlux

一、创建项目

这里我使用IDEA快速创建基于SpringBoot的工程,当然你也可以选spring.io 创建再导入到IDEA 中。

要创建WebFlux 项目,必须勾选ReactiveWeb而不是传统的Web ,这里为了简化代码使用到了Lombok。

image-20190601143817483

项目创建完后目录:

image-20190601145307937

POM 依赖,这里IDEA 自动给项目加上了spring-boot-starter-webflux。完整依赖如下:


        
            org.springframework.boot
            spring-boot-starter-webflux
        

        
            org.projectlombok
            lombok
            true
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
        
        
            io.projectreactor
            reactor-test
            test
        
    

二、编写Controller

从序篇 可知道,编写WebFlux 的Controller 可以沿用SpringMVC 的那一套,但是返回结果需要改成Mono或者Flux。

创建一个mono 接口,返回hello webflux,这里的Mono.just()方法会发射一个元素,创建响应式的接口就这么"简单”。

package com.fine.webfluxquickstart.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;

/**
 * @author finefine at: 2019-06-01 15:02
 */
@RestController
@RequestMapping("/api/")
public class HelloController {
    
    @GetMapping("mono")
    public Mono mono() {
        return Mono.just("hello webflux");
    }
}

那么来测试一下,浏览器地址输入 localhost:8080/api/mono

image-20190601154255193

其实呢,上面mono接口这种执行模式是同步非阻塞的,也就是Mono产生数据,和Mono与Http 之间的订阅消费都是在同一个线程。

image.png

那既然这样,到底是不是在同一个线程中呢,更改代码证明一下。

package com.fine.webfluxquickstart.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;

/**
 * @author finefine at: 2019-06-01 15:02
 */
@RestController
@RequestMapping("/api/")
@Slf4j
public class HelloController {

    @GetMapping("mono")
    public Mono mono() {
        return Mono.create(monoSink -> {
            log.info("创建 Mono");
            monoSink.success("hello webflux");
        })
        .doOnSubscribe(subscription -> { //当订阅者去订阅发布者的时候,该方法会调用
            log.info("{}",subscription);
        }).doOnNext(o -> { //当订阅者收到数据时,改方法会调用
            log.info("{}",o);
                });
    }
}
 
 

如图,Mono的创建和消费都是都是在ctor-http-nio-2 这个线程中,仔细看看这log的顺序,你会发现订阅动作在创建动作之前,最后是消费,那么为什么会这样呢?这个先留到后面讲,感兴趣的可以先去了解一下。

image-20190601170432212

之前提到了Mono 最多发射一个数据,Flux 可以发射多个数据,那么来写个Flux看看吧。

package com.fine.webfluxquickstart.controller;

        import lombok.extern.slf4j.Slf4j;
        import org.springframework.web.bind.annotation.GetMapping;
        import org.springframework.web.bind.annotation.RequestMapping;
        import org.springframework.web.bind.annotation.RestController;
        import reactor.core.publisher.Flux;
        import reactor.core.publisher.Mono;
        import reactor.core.scheduler.Schedulers;

/**
 * @author finefine at: 2019-06-01 15:02
 */
@RestController
@RequestMapping("/api/")
@Slf4j
public class HelloController {

    @GetMapping("mono")
    public Mono mono() {
        return Mono.create(monoSink -> {
            log.info("创建 Mono");
            monoSink.success("hello webflux");
        })
                .doOnSubscribe(subscription -> {
                    log.info("{}", subscription);
                }).doOnNext(o -> {
                    log.info("{}", o);
                });
    }

    @GetMapping("flux")
    public Flux flux() {
        return Flux.just("hello","webflux","spring","boot");
    }
}
 
 

这里Flux发射了4个数据,来看下结果:

image-20190601172604363

三、总结

WebFlux 应用中,所有数据都应该以Mono、Flux的形式表示,这样才能带来最好的性能和高吞吐量。Mono和Flux 这两种数据模型是WebFlux的核心,本片入门教程只是简单的展示了WebFlux项目的搭建编写,要学好WebFlux 还需要掌握Reactor(Mono、Flux),其实Reactor 和 Stream 的很多操作都有类似功能,如果你对Java8Stream非常熟悉的话,学习Reactor应该是也是件容易的事情,如果还不掌握Stream 建议先去学好Stream。
QQ群:577715614
源码

你可能感兴趣的:(快速上手WebFlux)