链接您的Publisher
,愿Context
与您同在
如果您连接了所有Publisher
(包括在flatMap
/concatMap
和类似运算符中的连接),则Context
将正确地在整个流程运行时传播。
要在nameToGreeting
方法中访问Context
,可以调用Mono.subscribeContext
并检索存储的信息,即使这些方法看起来不相关。以下示例展示了上述概念:
public class TestFlatMap {
public static void main(final String ...args) {
final Flux<String> greetings = Flux.just("Hubert", "Sharon")
.flatMap(TestFlatMap::nameToGreeting)
.subscriberContext(context ->
Context.of("greetingWord", "Hello")
);
greetings.subscribe(System.out::println);
}
private static Mono<String> nameToGreeting(final String name) {
return Mono.subscriberContext()
.filter(c -> c.hasKey("greetingWord"))
.map(c -> c.get("greetingWord"))
.flatMap(greetingWord -> Mono.just(greetingWord + " " + name + " " + "!!!"));
}
}
同时,您也可以使用zip
运算符以类似的方式进行操作,以便稍后组合结果:
public class TestFlatMap {
public static void main(final String ...args) {
final Flux<String> greetings = Flux.just("Hubert", "Sharon")
.flatMap(TestFlatMap::nameToGreeting)
.subscriberContext(context ->
Context.of("greetingWord", "Hello")
);
greetings.subscribe(System.out::println);
}
private static Mono<String> nameToGreeting(final String name) {
return Mono.zip(
Mono.subscriberContext()
.filter(c -> c.hasKey("greetingWord"))
.map(c -> c.get("greetingWord")),
Mono.just(name),
(greetingWord, receivedName) -> greetingWord + " " + receivedName + " " + "!!!"
);
}
}
那么,为什么它能工作?
从上面的示例中可以看出,nameToGreeting
在主 Flux
的上下文中被调用。在内部实现中->(这里是一些 FluxFlatMap 内部实现),每个映射的 Publisher
都由 FlatMapInner
订阅。如果我们查看 FlatMapInner
并查找 currentContext
重载,我们将看到,FlatMapInner
使用父级 Context
,这意味着如果父级拥有 Reactor Context
- 则此上下文将传播到每个内部的 Publisher
。
因此,返回的 Mono
,由 nameToGreeting
方法生成,将具有与其父级相同的 Context
。