首页 > 解决方案 > Mono.subscriberContext() 返回旧上下文

问题描述

我有一个带有方法 context() 的 PublishContext 类,如下所示:

public static Mono<Object> context(){

    return Mono.empty().subscriberContext( context -> {
        Context context1 = context.put("key", "hello");
        System.out.println((String) context1.get("key"));
        return context1;
    });
}

在上面的代码中,上下文对象是 Context0@744,而 context1 是 Context@747,这是可以理解的,因为上下文是不可变的,并且总是返回一个新的上下文。

在我的主课中,我有以下代码:

public static void main(String[] args) {

    Mono<Object> objectMono = PublishContext.context();
    objectMono.subscribe();

    Mono<Object> objectMono1 = Mono.subscriberContext().flatMap(context ->       {
        System.out.println((String) context.get("key"));
        return Mono.empty();
    });
    objectMono1.subscribe();
}

在这里,我将上下文作为 Context0@744,即旧上下文,因此,得到“上下文为空”异常。有人可以解释这种行为吗?另外,如何访问从 context() 方法返回的 context0@747 ?

标签: javareactive-programmingspring-webfluxproject-reactor

解决方案


  • A)Context写入需要是同一运营商链的一部分
  • B)它需要在您需要阅读的部分的“下游”

因此,一个“自包含”序列,其中您拥有源 ( Mono.empty())、Context写入 ( .subscriberContext(...)) 和订阅的最后一步 ( objectMono.subscribe()) 没有多大意义。

也许尝试context()变成一种装饰方法?

public static <T> Mono<T> addContext(Mono<T> source){
    return source.subscriberContext( context -> {
        Context context1 = context.put("key", "Hello");
        System.out.println((String) context1.get("key"));
        return context1;
    });
}

然后申请并阅读:

public static void main(String[] args) throws Exception {
    Mono<String> mono = Mono.just("foo")
        .flatMap(value -> Mono.subscriberContext()
            .map(ctx -> value + ctx.getOrDefault("key", "UNKNOWN"))
        );
    Mono<String> monoWithCtxWrite = addContext(mono);

    mono.subscribe(System.out::println);
    monoWithCtxWrite.subscribe(System.out::println);
}

这将打印(前提是 main 不会过早退出):

fooUNKNOWN
fooHello

推荐阅读