Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/spring-boot/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring boot 在doOnSubscribe、doOnSuccess和doOnError中获取反应器订阅者上下文_Spring Boot_Project Reactor - Fatal编程技术网

Spring boot 在doOnSubscribe、doOnSuccess和doOnError中获取反应器订阅者上下文

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

我正在尝试实现Reactor订户上下文(),这样我就可以将slf4jmdc中的值传递到一个通量中,然后使用这些值进行日志记录

我使用subscriberContext()方法设置值,如下所示:

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体系结构(以及上下文特性)的结果,因此这不太可能因取消而改变