Reactor
Reactor是基于Reactor-Stream实现反应式编程范例,一种面向数据流并传播事件的异步编程范式,也可以是同步;reactor-core包提供的核心类主要是:
Mono: 产生和处理0或1个事件
Flux:产生和处理0,,,N个事件
Mono静态方法创建
empty():创建一个不包含任何元素,只发布结束消息的序列
Mono.empty().subscribe(System.out::println);
just():可以指定序列中包含的全部元素。创建出来的 Mono序列在发布这些元素之后会自动结束。
Mono.just("foo").subscribe(System.out::println);
justOrEmpty():从一个 Optional 对象或可能为 null 的对象中创建 Mono。只有 Optional 对象中包含值或对象不为 null 时,Mono 序列才产生对应的元素。
Mono.justOrEmpty(null).subscribe(System.out::println);
error(Throwable error):创建一个只包含错误消息的序列
Mono.error(new RuntimeException("error")).subscribe(System.out::println, System.err::println);
never():创建一个不包含任何消息通知的序列
Mono.never().subscribe(System.out::println);
fromCallable()、fromCompletionStage()、fromFuture()、fromRunnable()和 fromSupplier():分别从 Callable、CompletionStage、CompletableFuture、Runnable 和 Supplier 中创建 Mono
//通过fromCallable创建 Mono.fromCallable(() -> "callable run ").subscribe(System.out::println); //通过fromSupplier创建 Mono.fromSupplier(() -> "create from supplier").subscribe(System.out::println);
Mono动态方法创建
通过 create()方法来使用 MonoSink 来创建 Mono。
Mono.create(sink->sink.success("create mono")).subscribe(System.out::println);
create操作符
@Test public void testFlux() { Flux<Integer> flux = Flux.create(new Consumer<FluxSink<Integer>>() { @Override public void accept(FluxSink<Integer> fluxSink) { fluxSink.next(1); fluxSink.next(2); fluxSink.complete(); fluxSink.next(3); } }); Subscriber<Integer> subscriber = new Subscriber<Integer>() { @Override public void onSubscribe(Subscription subscription) { subscription.request(Integer.MAX_VALUE); } @Override public void onNext(Integer integer) { log.info("消费:{}", integer); } @Override public void onError(Throwable throwable) { log.info("异常:{}", throwable.getMessage()); } @Override public void onComplete() { log.info("完成"); } }; flux.subscribe(subscriber); }
把被观察者比作上游流水线(也可以比作生产者);观察者比作下游流水线(消费者)

- fluxSink 就是发射器,可以发生N个事件,通过next() 完成
- 当fluxSink发射complete()或error()事件之后,fluxSink继续发生next()事件,但是下游流水线接受complete/error事件之后,停止接受任何事件;
- 下游接受到事件之后,进入onNext()方法;完成进入onComplete()方法,错误onError()方法
- 上游可以不发射complete()和error() 方法,管道处于监控状态,不会执行下游onComplete()方法;
just操作符
Flux.just("1", "2", "3").subscribe(new Subscriber<String>() {
@Override
public void onSubscribe(Subscription subscription) {
subscription.request(Integer.MAX_VALUE);
}
@Override
public void onNext(String s) {
log.info("元素:{}", s);
}
@Override
public void onError(Throwable throwable) {
log.error("异常:{}", throwable.getMessage());
}
@Override
public void onComplete() {
log.info("完成");
}
});
just 相当特殊数组,特殊数组可以同时存放,不同类型的数据
just和create区别:
create:根据需求手动创建事件并发送;
just: 将已有的数据交给Flux发送,发送完成之后会自定发送complete事件;
From 系列操作符
- fromStream: 放入jdk8的Stream流;
- fromIterable:放入一个集合,所有实现了Collection集合接口的类都可以放入,如List,Set集合;
- fromArray:放入一个数组;他和just区别是,just可以同时放如各种数据类型的数据;
- from: 类似发射器,更像一个回调函数,可以发生N个事件
Flux.from(new Publisher<Integer>() { @Override public void subscribe(Subscriber<? super Integer> subscriber) { subscriber.onNext(1); subscriber.onNext(1); subscriber.onComplete(); } }).subscribe(new Subscriber<Integer>() { @Override public void onSubscribe(Subscription subscription) { } @Override public void onNext(Integer s) { log.info("元素:{}", s); } @Override public void onError(Throwable throwable) { log.error("异常:{}", throwable.getMessage()); } @Override public void onComplete() { log.info("完成"); } });
- from :通过直接引入下游管道来传输数据,一旦上游流水线与下游流水线发生订阅,就把事件之间传递给下游;
- create 是一个发射器,发送的数据,需要下游发起请求并订阅,上游才会把事件传递给下游;
- 在onSubscribe方法中,create操作符需要调用s.request(Integer.MAX_VALUE); from才不需要这个调用
- Flux.empty() : 发送一个complete完成事件;
- Flux.error(Throwable error) 发射一个Throwable错误事件
- Flux.never() 不发送事件
interval 操作符
CountDownLatch latch = new CountDownLatch(1); Flux.interval(Duration.ofSeconds(2),java.time.Duration.ofSeconds(3)).subscribe(new Consumer<Long>() { @Override public void accept(Long aLong) { System.out.println(aLong+"=="+Thread.currentThread().getName()); } }); latch.await(); 输出内容: 0==parallel-1 1==parallel-1
Interval:每隔相应的时间发送一次,
第一个参数:第一次执行的延迟时间;第二个参数:每隔多少秒发送一次事件,发送的内容是Long类型整数,从0开始;
interval 默认是在子线程执行事件发送的
timeout 操作符
@Test public void testTimeout() { Flux.create(new Consumer<FluxSink<Integer>>() { @Override public void accept(FluxSink<Integer> fluxSink) { fluxSink.next(1); try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); } fluxSink.next(3); } }).timeout(Duration.ofSeconds(2), new Publisher<Integer>() { @Override public void subscribe(Subscriber<? super Integer> subscriber) { subscriber.onNext(100); } }).subscribe((Consumer<Integer>) integer -> log.info("消费:{}", integer)); }
- timeout :在超时之后做相应的时间
- 第一个参数:设置超时时间,设置了2秒,2秒上游没有把事件发送过来,进入timeout,发送一个2;
- 第二个参数:超时之后会进入的操作
- 上游一旦超时,就会丢失下面所有的事件,不会继续传给下游,之后走timeout的逻辑
defer 操作符
Flux<Integer> defer = Flux.defer(new Supplier<Publisher<Integer>>() { @Override public Publisher<Integer> get() { return Flux.just(new Random().nextInt(10)); } }); Subscriber<Integer> subscriber = new Subscriber<Integer>() { @Override public void onSubscribe(Subscription s) { s.request(3); } @Override public void onNext(Integer integer) { System.out.println("=="+integer); } @Override public void onError(Throwable t) { } @Override public void onComplete() { } }; defer.subscribe(subscriber);
- defer : 延迟初始化被观察者,直到上游流水线与下游流水线发生订阅后,才会创建被观察者。
delay系列操作符
CountDownLatch latch = new CountDownLatch(1); Flux.just("1","2","3").delayElements(Duration.ofSeconds(2)).subscribe(new Consumer<String>() { @Override public void accept(String s) { System.out.println(Thread.currentThread().getName()+"=="+s); } }); latch.await(); 输出结果: parallel-1==1 parallel-2==2 parallel-3==3
- delayElements: 每一个原始事件都会延迟2秒,才发送,知道发送完成
- 默认在子线程中完整
Map操作
@Test public void testMap() { List<User> userList = new ArrayList(); User user = new User(); user.setName("jim"); user.setAge(10); userList.add(user); List<String> userInfo = Flux.fromIterable(userList).map(us -> { StringBuffer buffer = new StringBuffer(us.getName()); buffer.append("-"); buffer.append(us.getAge()); return buffer.toString(); }).collectList().block(); log.info("{}", userInfo); }
FlatMap操作符
List<User> userList = new ArrayList(); User user = new User(); user.setName("anthony"); user.setAge(10); userList.add(user); Flux.fromIterable(userList).flatMap(new Function<User, Publisher<Set<Character>>>() { @Override public Publisher<Set<Character>> apply(User us) { char[] chars = us.getName().toCharArray(); Set<Character> phones = new HashSet<>(); for (char aChar : chars) { phones.add(aChar); } return Flux.just(phones); } }).subscribe(new Consumer<Set<Character>>() { @Override public void accept(Set<Character> characters) { System.out.println(characters.toString()); } });
flatmap 和map使用类型,map返回一个具体对象类型,flatmap更加灵感,返回一个新的被观察者
mergeWith
- 将一个事件插入到原来的事件中;
- 类似于将List集合中插入一条数据,但是插入在List集合的末尾
- 和zipwith不同的是,他不与源事件合并,而是插入新的事件;
reduce:
将所有数据聚合在一起之后,在传给下游流水线,最后只传递了一个事件给下游
Flux.just(1, 2, 3, 4, 5).reduce(new BiFunction<Integer, Integer, Integer>() { @Override public Integer apply(Integer param1, Integer param2) { log.info("{}加上{}", param1, param2); return param1 + param2; } }).subscribe(new Consumer<Integer>() { @Override public void accept(Integer integer) { log.info("结果:{}", integer); } });
buffer
buffer 就将单个数据分组聚合,3就是几个事件合并为一个组,然后发送出去的是一个List集合;如果最后的数据撮不成3了,就使用余数存放到一个List集合进行发送
Flux.just(1, 2, 3, 4, 5, 6, 7).buffer(3).subscribe(new Consumer<List<Integer>>() { @Override public void accept(List<Integer> integers) { log.info("{}", integers); } }); ------------结果----------------- : [1, 2, 3] : [4, 5, 6] : [7]
groupBy
- groupBy 将事件按照某种规则进行分组,同时将分组id传递给下游;分组之后传递给下游的是一个被观察者(生产者);
- 与buffer组合发送不同,这里还是一个个事件往下传递
Flux.just(1, 2, 3, 4, 5, 6, 7, 8).groupBy(new Function<Integer, Integer>() { @Override public Integer apply(Integer integer) { return integer % 3; } }).subscribe(new Consumer<GroupedFlux<Integer, Integer>>() { @Override public void accept(GroupedFlux<Integer, Integer> groupedFlux) { groupedFlux.subscribe(new Consumer<Integer>() { @Override public void accept(Integer integer) { log.info("分组id={},值为:{}", groupedFlux.key(), integer); } }); } });
分组id=1 ==值==1
分组id=2 ==值==2
分组id=0 ==值==3
分组id=1 ==值==4
分组id=2 ==值==5
分组id=0 ==值==6
分组id=1 ==值==7
分组id=2 ==值==8
handler
handler :在事件传递的中间环节做数据的处理,处理过程中如果产生多个新的事件,通过发射器继续将新事件往下传递
注意的是,handler对源事件进行处理之后传递一个新的事件,每次只能传递一个不能多传;
Flux.just("15", "66", "", "33").filter(new Predicate<String>() {
@Override
public boolean test(String s) {
if (StringUtils.isEmpty(s)) {
return false;
}
return true;
}
}).handle(new BiConsumer<String, SynchronousSink<Integer>>() {
@Override
public void accept(String s, SynchronousSink<Integer> integerSynchronousSink) {
integerSynchronousSink.next(Integer.valueOf(s));
}
}).subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) {
log.info("结果:{}", integer);
}
});
doOnNext
- doOnNext :是事件的中间处理流程,不能改成源事件类型以及发射新的事件;
- 即使在中间改变了传递来值,不会改变源事件中的值;
- 如果对象引用类型,如传递UserVO对象,doOnNext对UserVO属性name修改,它传递name就会发生变化
Flux.just("15", "66", "", "33").filter(new Predicate<String>() {
@Override
public boolean test(String s) {
if (StringUtils.isEmpty(s)) {
return false;
}
return true;
}
}).doOnNext(new Consumer<String>() {
@Override
public void accept(String s) {
log.info("{}", s);
s = "555";
}
}).subscribe(new Consumer<String>() {
@Override
public void accept(String str) {
log.info("结果:{}", str);
}
});
doOnError 使用和doOnNext相似,就是出现错误后,中间逻辑处理
doOnComplete 使用和doOnNext相似,整个事件流完成之后应该做些什么事情
retry 操作符
retry :当处理流程中出现错误时,是否发起重试
- 第一个参数:最大重试次数
- 第二个参数:出现错误之后是否重试返回true:重试,false不重试
Flux.just(1, 2).handle(new BiConsumer<Integer, SynchronousSink<Integer>>() { @Override public void accept(Integer elem, SynchronousSink<Integer> integerSynchronousSink) { if (1 == elem) { integerSynchronousSink.error(new RuntimeException("错误")); } else { integerSynchronousSink.next(elem + 10); } } }).retry(2, new Predicate<Throwable>() { @Override public boolean test(Throwable throwable) { log.info("重试:{}", throwable.getMessage()); if (throwable instanceof RuntimeException) { log.info("异常:{}", throwable.getMessage()); } return false; } }).onErrorResume(new Function<Throwable, Publisher<Integer>>() { @Override public Publisher<Integer> apply(Throwable throwable) { log.info("使用0代替"); return Flux.just(0); } }).subscribe(new Consumer<Integer>() { @Override public void accept(Integer integer) { log.info("结果:{}", integer); } });
onErrorResume:在捕获到错误之后,应该做点什么错误处理的逻辑,返回的是一个发射器;这里没有做错误的逻辑处理,直接返回Flux.just(0),在项目中可以根据具体需要做处理;
浙公网安备 33010602011771号