SpringCloudGateway源码解析(2)-反应式编程

SpringCloudGateway源码解析(2)-反应式编程

​ 反应式编程,作为一种新的思想,以函数式编程为基础,受到越来越多的开发人员欢迎,Spring5作为行业的标准,也全面拥抱了Reactor框架。

前言

​ 为了应对 高并发环境下 的服务端编程,微软提出了一个实现 异步编程 的方案 - Reactive Programming,中文名称 反应式编程。Java也汲取了反应式编程的思想,Spring Reactor应势而生。Spring5.0以WebFlux为代表全面拥抱了Reactor的编程模式。Spring Cloud Gateway底层是webFlux,而webFlux就是基于Spring Reactor构建的新一代WEB框架。

想读懂Spring Cloud Gateway,先学Reactor

博主在读Spring Cloud Gateway源码之前,对Reactor技术不了解,在看Gateway源码时候不知道所谓了Flux和Mono是个啥概念。比如如下这段代码

1
2
3
4
5
6
7
8
9
10
11
12
13
public Mono<Void> filter(ServerWebExchange exchange) {
return Mono.defer(() -> {
if (this.index < filters.size()) {
GatewayFilter filter = filters.get(this.index);
DefaultGatewayFilterChain chain = new DefaultGatewayFilterChain(this,
this.index + 1);
return filter.filter(exchange, chain);
}
else {
return Mono.empty(); // complete
}
});
}

所以想读懂Gateway的源码,Reactor技术也是要掌握的,至少能了解Reactor的思想,知道它API的含义。接下来会带着大家对Reactor入个门,为后续的学习Gateway源码打好基础。

Flux原理

Flux表示的是包含0到N个元素的异步序列。下图中,operator上面共有6个元素,时间轴从左到右,分边进入到operator容器中进行处理,处理之后的结果流入到result flux中,有些情况下某些元素在处理过程中会出现错误。

img

Mono原理

Mono表示的是包含0-1个元素的异步序列,是一个特殊的Flux。原理和Flux一致,只是Mono限制了元素的数量。

反应式编程的所有API都在Flux和Mono中体现。

Reactor示例代码

Flux 可以根据fromIterable,just,fromArray 三种API创建异步序列。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
private static List<String> strs =    Arrays.asList("the","quick","brown","fox","jumped","over","the","lazy","dog");

public static void test0() {

Flux.fromIterable(strs).subscribe(System.out::println);
Flux.just(strs).subscribe(System.out::println);
String[] strArray = {"a", "b", "c", "d"};
Flux.fromArray(strArray).subscribe(System.out::println);
}

结果:
the
quick
brown
fox
jumped
over
the
lazy
dog
[the, quick, brown, fox, jumped, over, the, lazy, dog]
a
b
c
d

创建一个Flux和一个Mono,flatMap函数按空字符串把happy字符串拆分成h,a,p,p,y这些子字符串,concatWith融合了s字符串,然后调用distinct和sort函数,完成了去重和排序,最终通过zipWith拼接数字.

1
2
3
4
5
6
7
8
9
10
11
12
13
public static void test3() {
List<String> list = Arrays.asList("happy");
Mono<String> missting = Mono.just("s");
Flux.fromIterable(list).flatMap(word -> Flux.fromArray(word.split(""))).concatWith(missting)
.distinct().sort().zipWith(Flux.range(1, Integer.MAX_VALUE), (string, count) -> String.format("%d. %s", count, string)).subscribe(System.out::println);
}

结果:
1. a
2. h
3. p
4. y
5. s

总结

反应式编程范式对于习惯了传统编程范式的开发人员来说,既是一个需要进行思维方式转变的挑战,也是一个充满了更多可能的机会。Reactor 作为一个基于反应式流规范的新的 Java 库,可以作为反应式应用的基础。但是Reactor还不算成熟,以后的发展还需拭目以待,至少Spring已经全面拥抱。

#参考文档

聊聊Spring Reactor反应式编程

Reactive programming 一种技术 各自表述

Java 8函数式接口functional interface的秘密

Reactor官方文档

使用 Reactor 进行反应式编程

评论