Создайте цепочку Publisher
с, и пусть Context
будет с вами
В этом случае вы подключили все свои Publisher
с (и это включает в себя соединения в пределах flatMap
/ concatMap
и аналогичные операторы) Context
будет правильно распространяться по всей среде выполнения потока.
Для доступа к Context
в методе nameToGreeting
вы можете вызвать 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") // context initialized
);
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 + " " + "!!!"));// ALERT: we have Context here !!!
}
}
Кроме того, вы можете сделать то же самое следующим образом, используя оператор 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") // context initialized
);
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")), // ALERT: we have Context here !!!
Mono.just(name),
(greetingWord, receivedName) -> greetingWord + " " + receivedName + " " + "!!!"
);
}
}
Итак,почему это работает?
Как видно из примера выше, nameToGreeting
вызывается в контексте основного Flux
.Под капотом -> (Здесь некоторые внутренние компоненты FluxFlatMap) , каждое сопоставленное Publisher
подписано FlatMapInner
.Если мы посмотрим на FlatMapInner
и ищем currentContext
переопределение , мы увидим, что FlatMapInner
использует родительский Context
, что означает, что у родителя есть ReactorContext
- тогда этот контекст будет распространяться на каждый внутренний Publisher
.
Следовательно, возвращаемый методом nameToGreeting
1042 * будет иметь тот же Context
, что и его родительский