Spring boot 在doOnSubscribe、doOnSuccess和doOnError中获取反应器订阅者上下文
我正在尝试实现Reactor订户上下文(),这样我就可以将slf4jmdc中的值传递到一个通量中,然后使用这些值进行日志记录 我使用subscriberContext()方法设置值,如下所示:Spring boot 在doOnSubscribe、doOnSuccess和doOnError中获取反应器订阅者上下文,spring-boot,project-reactor,Spring Boot,Project Reactor,我正在尝试实现Reactor订户上下文(),这样我就可以将slf4jmdc中的值传递到一个通量中,然后使用这些值进行日志记录 我使用subscriberContext()方法设置值,如下所示: someFlux().subscriberContext(Context.of(MDC_ATTRIBUTE, MDC.get(MDC_ATTRIBUTE))); 我还可以访问链中的上下文。例如,对于平面图: .flatMap(r -> Mono.subscriberContext().map(ct
someFlux().subscriberContext(Context.of(MDC_ATTRIBUTE, MDC.get(MDC_ATTRIBUTE)));
我还可以访问链中的上下文。例如,对于平面图:
.flatMap(r -> Mono.subscriberContext().map(ctx -> {
String name = ctx.getOrDefault(MDC_ATTRIBUTE_NAME, "NO CTX");
return r;
}))
同样doOnEach()
也可以工作:
.doOnEach(signal -> {
Context ctx = signal.getContext();
if (signal.isOnNext()) {
try (MDC.MDCCloseable closeable = MDC.putCloseable(MDC_ATTRIBUTE_NAME, ctx.getOrDefault(MDC_ATTRIBUTE_NAME, "MAAAAN"))) {
log.debug("FINISHED: {}", requestName);
}
}
})
它只有一个问题。我想在doOnSubscribe
、doOnError
和doOnSuccess
中登录一些内容。虽然我可以使用doOnEach检查signal.isOnNext()
或signal.isOnComplete()
,但我发现从未调用signal.isOnSubscribe()
所以问题是:我如何才能在
doOnSubscribe()
中获得上下文,或者这根本不可能吗?这是可能的,不是在100%的用例中,而且需要一些技巧:
Flux.just("foo")
.doOnSubscribe(sub -> {
Scannable actual = Scannable.from(sub).scan(Scannable.Attr.ACTUAL);
if (actual instanceof CoreSubscriber) {
Context context = ((CoreSubscriber) actual).currentContext();
System.out.println(context);
}
})
.map(v -> "value: " + v) //below or above doOnSubscribe is fine
.subscriberContext(Context.of("foo", "bar")) //MUST be below doOnSubscribe
.blockLast();
即使通量为空,您是否希望引发订阅事件?doOnCancel()如何?在这种情况下有可能访问它吗?没有。特别是因为当取消信号到达您的DoonCancel时,与保存上下文的实际下游用户的联系可能已经断开了,所以目前不可能。这也不可行吗?是否值得为此创建一个特性请求?这是整个reactor体系结构(以及上下文特性)的结果,因此这不太可能因取消而改变