我的 Spring webflux flatMap、doOnNext、doFinally 没有被内部 Mono 调用?

My Spring webflux flatMap, doOnNext, doFinally is not getting called for inner Mono?

我对 reactor 完全陌生。 我的 flatMap、doOnNext、doFinally 没有被内部 Mono 调用。 我添加了描述问题的样本测试和输出。即使我将 getMeIntegerMono2getMeStringMono 互换,它也不会被调用, 我做错了什么吗?

@Test
    public void prodBug() {
        System.out.println(Final());
    }

    String Final(){
        final String[] val = new String[1];
        System.out.println("1 - "+Thread.currentThread().getName());

        Mono<Integer> intMono =
                getMeIntegerMono("2")
                        .doOnNext(integer -> {
                            getMeIntegerMono2("21")
                                    .flatMap(s -> getMeStringMono(String.valueOf(s)));
                        });

        System.out.println("2 - "+Thread.currentThread().getName());

        intMono.subscribe(integer -> {
            val[0] =String.valueOf(integer);
        });
        System.out.println("3 - "+Thread.currentThread().getName());
        return val[0];
    }

    Mono<String> getMeStringMono(String val){
        System.out.println("String Mono - "+Thread.currentThread().getName());
        return Mono.just(val);
    }


    Mono<Integer> getMeIntegerMono(String val){
        System.out.println("Integer Mono - "+Thread.currentThread().getName());
        return Mono.just(Integer.parseInt(val));
    }

    Mono<Integer> getMeIntegerMono2(String val){
        System.out.println("Integer Mono2 - "+Thread.currentThread().getName());
        return Mono.just(Integer.parseInt(val));
    }

输出是

1 - main
Integer Mono - main
2 - main
Integer Mono2 - main
3 - main
2

进程已完成,退出代码为 0

您的代码存在一些问题。

在 Reactor 中,nothing happens until you subscribe。也就是说,仅仅创建一个 Mono 不会 任何事情。在传递给 doOnNext 的函数中,您创建了一个从未被订阅的 Mono。因此,您传递给 flatMap 的函数将永远不会被调用。尝试使用 flatMap 而不是 doOnNext(您需要 fiddle 稍微调整一下类型才能使其正常工作)。

您测试此方法的一个问题来自 "assembly time" 和 "execution time." 之间的 difference 在您所有的 getMe* 方法中,您立即打印一些东西并然后 return 一个单声道。这实际上在调试时具有误导性,因为打印将在汇编期间发生,即使从未执行 returned Mono。您可以在执行时执行副作用,而不是使用 Mono.defer()Mono.fromSupplier().

使用数组来绕过 Java 对变量和 lambda 的限制的技术是不好的做法,虽然它在这种情况下可能有效,但您应该改掉这种习惯,因为它非常脆弱。要理解原因,请想象您的链中的某个 Mono 在另一个线程中执行昂贵的操作。这意味着您传递给 subscribe 的函数将在 Final() 已经 return 之后被调用。