1. 概述

在这个简短教程中,我们将探讨Spring 5 WebFlux中Mono对象的各种监听器。我们将比较doOnNext()doOnSuccess()方法,并发现尽管它们相似,但在处理空的Mono时,它们的行为却有所不同。

2. doOnNext

Mono的doOnNext()允许我们添加一个监听器,当数据被发出时,它会被触发。在本文的代码示例中,我们将使用PaymentService类。在这种情况下,我们仅在paymentMono发出数据时调用processPayment方法,通过使用doOnNext()

@Test
void givenAPaymentMono_whenCallingServiceOnNext_thenCallServiceWithPayment() {
    Payment paymentOf100 = new Payment(100);
    Mono<Payment> paymentMono = Mono.just(paymentOf100);

    paymentMono.doOnNext(paymentService::processPayment)
        .block();

    verify(paymentService).processPayment(paymentOf100);
}

然而,空的Mono不会发出任何数据,因此doOnNext不会被触发。因此,如果我们使用Mono.empty()重试测试,processPayment方法不应再被调用:

@Test
void givenAnEmptyMono_whenCallingServiceOnNext_thenDoNotCallService() {
    Mono<Payment> emptyMono = Mono.empty();

    emptyMono.doOnNext(paymentService::processPayment)
        .block();

    verify(paymentService, never()).processPayment(any());
}

3. doOnSuccess

我们可以使用doOnSuccess来添加一个监听器,当Mono成功完成时,它将被触发。让我们重复测试,但这次使用doOnSuccess

@Test
void givenAPaymentMono_whenCallingServiceOnSuccess_thenCallServiceWithPayment() {
    Payment paymentOf100 = new Payment(100);
    Mono<Payment> paymentMono = Mono.just(paymentOf100);

    paymentMono.doOnSuccess(paymentService::processPayment)
        .block();

    verify(paymentService).processPayment(paymentOf100);
}

但是,我们应该注意,即使不发出数据,Mono也被认为是成功完成的。因此,对于空的Mono,上述代码会用一个nullPayment调用processPayment方法:

Test
void givenAnEmptyMono_whenCallingServiceOnSuccess_thenCallServiceWithNull() {
    Mono<Payment> emptyMono = Mono.empty();

    emptyMono.doOnSuccess(paymentService::processPayment)
        .block();

    verify(paymentService).processPayment(null);
}

4. 总结

在这篇短文中,我们了解了Mono的doOnNextdoOnSuccess监听器之间的区别。如果我们想对接收到的数据作出反应,可以使用doOnNext。另一方面,如果我们希望在Mono成功完成时调用方法,无论是否发出数据,都应该使用doOnSuccess

如往常一样,本文的代码可以在GitHub上找到。