一、前言
Spring5是基于Reactor框架实现响应式流,其中Spring Boot WebFlux是完全依赖reactor-core来实现;直接上手Spring WebFlux,虽然能简单使用,但对其原理未做深入了解,难免会有不少迷惑,故建议从基础出发,按照如下步骤进行学习:
1、掌握JDK8的函数式编程及stream流;
2、学习JDK9的flux的响应式流设计原理及实现机制
3、上手spring Boot webflux(JDK8函数式编程及stream流 + JDK9响应式流 的结合)
二、JDK8中的函数式编程及stream流
jdk8中最大的特点之一就是支持函数式编程及stream流,下面就其中重点做下基本的简介和示例:
(一)lamda表达式
Lambda 表达式,也可称为闭包,本质上来说其允许把函数作为一个方法的参数。
public class LambdaDemo1 {
public static void main(String[] args) {
// 非lambda表达式代码示例
Runnable thread1 = new Runnable() {
@Override
public void run() {
System.out.println("普通线程");
}
};
new Thread(target).start();
// jdk8 lambda表达式代码示例
//返回一个接口,可以使用强转的方式(不过我觉得应该没人这么用)
Runnable thread2 = (Runnable)() -> System.out.println("ok");
new Thread(thread2).start();
}
}
通过上面示例,可看出lambda表单式的很大的一个特点就是把复杂的代码逻辑,变得更为简洁和紧凑。
另外,lambda表达式还有其他的如下写法:
interface InterfaceDemo1 {
int doubleNum(int i);
int addNum(int i1, int i2);
}
public class LambdaDemo1 {
public static void main(String[] args) {
// 函数逻辑多行时,需要加大括号
InterfaceDemo1 i1 = (int i) -> {
System.out.println("----------");
return i * 2;
};
// 函数逻辑仅为一行时,可省去大括号和return
InterfaceDemo1 i2 = (int i) -> i * 2;
// 参数可省去类型
InterfaceDemo1 i3 = (i) -> i * 2;
// 单个参数时,可以省去括号
InterfaceDemo1 i4 = i -> i * 2;
// 多个参数时,需要加括号
InterfaceDemo1 i5 = (i1, i2) -> i1 + i2;
}
}
(二)函数式接口
函数式接口:只有一个方法的interface接口,一般通过添加注解 @FunctionalInterface来标注(不添加注解也可以,但建议加上注解以供编译时检验,加上注解后如果有多个方法会报错)
默认接口: interface接口中使用default关键字标注的实现方法;该方法可以不被实现,也可以被重写,和类中的方法一样,可以在方法使用this调用接口中的方法。
@FunctionalInterface
interface InterfaceDemo2 {
// jdk8之后建议接口设计尽量的小,一个接口只做一件事,也就是更加便于函数式接口的使用
int doubleNum(int i);
// 默认方法
default int add(int x, int y) {
return x + y;
}
}
public class LambdaDemo2 {
public static void main(String[] args) {
InterfaceDemo2 i1 = i -> i * 2;
// 调用接口默认方法
System.out.println(i1.add(3, 7));
System.out.println(i1.doubleNum(20));
}
}
(三)内置函数接口
1、四大核心函数式接口
| 函数式接口 | 参数类型 | 返回类型 | 方法 | 说明 |
|---|---|---|---|---|
| Consumer | T | void | void accept(T t) | 无返回值,对指定T类型参数进行处理 |
| Supplier | 无 | T | T get() | 无入参,通过处理返回指定T类型对象 |
| Function<T,R> | T | R | R apply(T) | 对指定T类型参数进行处理,通过处理返回指定R类型对象 |
| Predicate | T | boolean | boolean test(T) | 对指定T类型参数进行处理,判断是否满足某种条件 |
public class FunctionDemo1 {
public static void main(String[] args) {
// Consumer<T>
Consumer<String> consumer = s -> System.out.println(s);
consumer.accept("1");
// Supplier<T>
Supplier<String> supplier = () -> "2";
System.out.println(supplier.get());
// Function<T,R>
Function<Integer, Integer> function = i -> i * 2;
System.out.println(function.apply(3));
// Predicate<T>
Predicate<Integer> predicate = i -> i > 0;
System.out.println(predicate.test(-4));
}
}
2、 其他演变函数式接口
| 函数式接口 | 参数类型 | 返回类型 | 方法 | 说明 |
|---|---|---|---|---|
| BiFunction<T,U,R> | T,U | R | R apply(T t, U u) | 对指定T类型和U类型参数进行处理,通过处理返回指定R类型对象 |
| UnaryOperator | T | T | T apply(T t) | 对指定T类型参数进行处理,通过处理返回相同T类型对象, 其是Function<T,R>子接口 |
| BinaryOperator | T,T | T | T apply(T t, T t) | 对两个指定的T类型参数进行处理,通过处理返回相同T类型对象, 其是BiFunction<T,U,R>子接口 |
| BiConsumer<T,U> | T,U | void | void accept(T t,U u) | 无返回值,对指定T类型和U类型参数进行处理 |
(四)stream流
Stream流是一个来自数据源的元素队列并支持聚合操作,其有如下三个要素:
- 元素:特定类型的对象,基于该类型对象形成一个队列,且Stream流并

最低0.47元/天 解锁文章
1315

被折叠的 条评论
为什么被折叠?



