spring boot webflux响应式初探

612 阅读2分钟

这是我参与11月更文挑战的第1天,活动详情查看:2021最后一次更文挑战

最近工作中需要用到响应式编程。之前一直是spring web开发,对响应式编程知之甚少。webFlux相对于spring mvc而言,又是一种web开发框架,熟悉的spring mvc开发通过@RestController注解以及@RequestMapping等注解的配合使用 比如: @RestController @RequestMapping("flux") public class MonoFluxController {

@GetMapping("/index")
public String index() {
    return "index";
}

}

而spring5.0版本新引入的基于Reactive Streams的Spring WebFlux框架,主要基于Router Functions、WebFlux、Reactive Streams三个新组件;

  • Router Functions: 对标@Controller,@RequestMapping等标准的Spring MVC注解,提供一套函数式风格的API,用于创建Router,Handler和Filter。
  • WebFlux: 核心组件,协调上下游各个组件提供响应式编程支持。
  • Reactive Streams: 一种支持背压(Backpressure)的异步数据流处理标准,主流实现有RxJava和Reactor,Spring WebFlux默认集成的是Reactor。 Spring WebFlux都会将其输入输出流适配成Flux格式,以便进行统一处理。 值得一提的是,除了新的Router Functions接口,Spring WebFlux同时支持使用老的Spring MVC注解声明Reactive Controller。和传统的MVC Controller不同,Reactive Controller操作的是非阻塞的ServerHttpRequest和ServerHttpResponse,而不再是Spring MVC里的HttpServletRequest和HttpServletResponse。
// WebFlux(返回的是Mono) vWebFlux的好处:能够以固定的线程来处理高并发
@GetMapping("/2")
private Mono<String> get2() {
    log.info("get2 start");
    Mono<String> result = Mono.fromSupplier(() -> createStr());
    log.info("get2 end.");
    return result;
}

Flux和Mono是Reactor的数据流类型,Flux支持发送0次和N次,Mono支持发送0次和1次,如果返回的数据集,需要用Flux。响应式编程的开发需对的JDK8的Lamda表达式有一定的学习和使用。 实现spring boot的webFlux方式有两种,一种基于spring webmvc的注解方式,一种基于函数式编程的Hander和Router,这里主要实现第二种。 创建一个spring boot工程,添加POM依赖包 org.springframework.boot spring-boot-starter-webflux

编写一个处理时间的handler

@Component
public class TimeHandler {

    public Mono<ServerResponse> getTime(ServerRequest serverRequest) {
            return ok().contentType(MediaType.TEXT_PLAIN).body(Mono.just("Now is " + new SimpleDateFormat("HH:mm:ss").format(new Date())), String.class);
        }
    public Mono<ServerResponse> getDate(ServerRequest serverRequest) {
        return ok().contentType(MediaType.TEXT_PLAIN).body(Mono.just("Today is " + new SimpleDateFormat("yyyy-MM-dd").format(new Date())), String.class);
    }
}

注意TimeHandler是要加@Component注解或者@Cofiguration注解,注入spring容器。

再编写一个router

@Configuration
public class TimeRouter {

    @Autowired
    private TimeHandler timeHandler;

    @Bean
    public RouterFunction<ServerResponse> timerRouter() {
        return route(GET("/time"), req -> timeHandler.getTime(req))
                .andRoute(GET("/date"), timeHandler::getDate);  // 这种方式相对于上一行更加简洁
    }
}

TimeRouter同样注入。

这时,我们启动spring boot工程,谷歌浏览器输入:http://localhost:8080/time 输出:``` Now is 18:32:02

这样第一个简单的webFlux工程已经跑通了,下次会继续学习。