响应式编程
响应式编程(reactive programming)是一种基于数据流(data stream)和变化传递(propagation of change)的声明式(declarative)的编程范式
变化传递
在命令式编程(我们的日常编程模式)下,式子a=b+c,这就意味着a的值是由b和c计算出来的。如果b或者c后续有变化,不会影响到a的值
在响应式编程下,式子a:=b+c,这就意味着a的值是由b和c计算出来的。但如果b或者c的值后续有变化,会影响到a的值
数据流和声明式
把要处理的数据抽象出来(变成了数据流),然后通过API去处理数据流中的数据(是声明式的)
public static void main(String[] args) {
int[] nums = { 1, 2, 3 };
int sum2 = IntStream.of(nums).parallel().sum();
System.out.println("结果为:" + sum2);
}
响应式编程它是异步的,也可以理解成变化传递它是异步执行的。JDK8 Stream流是同步的,它就不适合用于响应式编程。JDK9 已经支持响应式流
入门WebFlux
WebFlux是Spring推出响应式编程的一部分(web端)
响应式编程是异步非阻塞的(是一种基于数据流(data stream)和变化传递(propagation of change)的声明式(declarative)的编程范式)
WebFlux使用的响应式流并不是用JDK9平台的,而是一个叫做Reactor响应式流库。
Reactor是一个响应式流,它也有对应的发布者(Publisher ),Reactor的发布者用两个类来表示:
Mono(返回0或1个元素)
Flux(返回0-n个元素)
而订阅者则是Spring框架去完成
例子
// 阻塞5秒钟
private String createStr() {
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
}
return "some string";
}
// 普通的SpringMVC方法
@GetMapping("/1")
private String get1() {
log.info("get1 start");
String result = createStr();
log.info("get1 end.");
return result;
}
// WebFlux(返回的是Mono)
@GetMapping("/2")
private Mono<String> get2() {
log.info("get2 start");
Mono<String> result = Mono.fromSupplier(() -> createStr());
log.info("get2 end.");
return result;
}
WebFlux还支持服务器推送(SSE - >Server Send Event)
/**
* Flux : 返回0-n个元素
* 注:需要指定MediaType
* @return
*/
@GetMapping(value = "/3", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
private Flux<String> flux() {
Flux<String> result = Flux
.fromStream(IntStream.range(1, 5).mapToObj(i -> {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
}
return "flux data--" + i;
}));
return result;
}
Comments