Webflux
简介
webflux是spring推出的响应式web框架,它的对标产品为spring-mvc, 与传统的spring-mvc相比较,webflux是完全非阻塞式的。
Webflux 特点:
第一 非阻塞式:在有限资源下,提高系统吞吐量和伸缩性,以 Reactor 为基础实现响应式编程。
第二 函数式编程:Spring5 框架基于 java8,Webflux 使用 Java8 函数式编程方式实现路由请求。
同步与异步,阻塞与非阻塞
同步:调用者发送请求,一直等待回应再去做其他的事情。
异步,调用者发送请求,不等对方回应就去做其他事情。
阻塞,被调用者受到请求之后,做完请求任务之后才给出反馈
非阻塞,被调用者受到请求之后,马上给出反馈再去做事情。
响应式编程
响应式编程是一种编程示例,可促进异步,非阻塞,事件驱动的数据处理方法。 响应式编程涉及将数据和事件建模为可观察的数据流,并实现数据处理例程以对这些流中的更改做出反应。
响应式编程可以理解为,当某一主题发生改变时,观察此主题的观察者就会立刻收到通知并做出一系列相应。
举个例子,在一个数据系统中,如果数据发生了变化,就会触发相应一系列的变化,数据改变,数据访问层发生变化,业务逻辑层发生变化 ,控制器发生变化,UI也做出相应的变化。
观察者模式
public class Observe extends Observable { public static void main(String[] args){ Observe observe=new Observe(); /* * 响应式编程 * */ //添加观察者 observe.addObserver((o,arg)->{ System.out.println("实施改变"); }); observe.addObserver((o,arg)->{ System.out.println("接受通知,准备改变"); }); observe.setChanged();//数据变化 observe.notifyObservers();//通知 } }
SpringWebflux 基于 Reactor,默认使用容器是 Netty,Netty 是高性能的 NIO 框架,异步非阻塞的框架。
NIO是一种同步非阻塞的I/O模型,也是I/O多路复用的基础,已经被越来越多地应用到大型应用服务器,成为解决高并发与大量连接、I/O处理问题的有效方式。
NIO
在响应式编程操作中,Reactor 是满足 Reactive 规范框架。Reactor 有两个核心类,Mono 和 和 Flux ,这两个类实现接口 Publisher,提供丰富操作 ,提供丰富操作符。
- Flux 对象实现发布者,返回 N 个元素;
- Mono 实现发布者,返回 0 或者 1 个元素
Flux示意图:
Mono示意图:
引入依赖
<!--flux响应式编程--> <dependency> <groupId>io.projectreactor</groupId> <artifactId>reactor-core</artifactId> <version>3.1.15.RELEASE</version> </dependency>
public class flux { public static void main(String[] args){ //flux 返回多个元素 //mono 返回0或1个元素 Flux.just(1,2,3,4).subscribe(System.out::println); Mono.just(1).subscribe(System.out::println); Integer[] arr={1,2,3}; Flux.fromArray(arr); List<Integer> list= Arrays.asList(arr); Flux.fromIterable(list); Stream<Integer> stream=list.stream(); Flux.fromStream(stream); } }
使用
导入依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-webflux</artifactId> </dependency>
基于注解的webflux
@GetMapping("/mono") public Mono<String> mono(){ return Mono.just("mono"); } @GetMapping("/flux") public Flux<String> flux(){ return Flux.just("flux"); }
基于函数式编程的webflux
创建RouterFunction,将其注入到Spring中即可。
@Bean pubulic RouterFuntion<ServerResponse> test01(){ return RouterFuntions.route().Get("/flux/function",new HandlerFunction<ServerResponse>(){ @Override public Mono<ServerResponse> handle(ServerRequest requrest){ return ServerResponse.ok().bodyValue("hello"); } }).build(); }
flux与Mono的相应式编程延迟案例
@GetMapping("/test") public Mono<String> stringMono(){ Mono<String> from=Mono.fromSupplier(() -> { try{ TimeUnit.SECONDS.sleep(5); }catch(InterruptedException e){ throw new RuntimeException(e); } return "hello"+LocalDateTime.now(); }); return from; }