当前位置: 首页 > 知识库问答 >
问题:

Spring被动-重用单值

汤嘉平
2023-03-14

我使用flatMap进行了一系列Mono转换。我设法将我的生产代码简化为这个测试用例:

@Test
public void test() {
    AtomicInteger iCounter = new AtomicInteger(1);
    Mono<String> iValueMono = Mono.fromSupplier(() -> {
        int iValue = iCounter.getAndIncrement();
        System.out.println("iValueMono CALL: " + iValue);
        return String.valueOf(iValue);
    });

    Mono<String> resultMono = Mono.just("X")
            .flatMap(append(iValueMono))
            .flatMap(append(iValueMono));

    StepVerifier.create(resultMono)
            .consumeNextWith(result -> assertThat(result).isEqualTo("X11"))
            .expectComplete()
            .verify();
}

private Function<String, Mono<String>> append(Mono<String> sMono) {
    return s -> sMono.map(v -> s + v);
}

这张照片是:

iValueMono CALL: 1
iValueMono CALL: 2

org.junit.ComparisonFailure: 
Expected :"X11"
Actual   :"X12"

我想——我现在知道这是不正确的——每次我在append()调用中映射iValueMono,供应商都会被重新执行以产生一个新的值。我无法在生产代码中更改iValueMono的实现方式(例如,使其有状态地存储值)。我如何实现这一点,以便只调用一次值供应商,并得到最终结果“X11”?

当然,我对一种非阻塞、反应式的方法感兴趣。

共有2个答案

章高朗
2023-03-14

我重写了你的测试,现在iValueMono只执行一次,看起来:

@Test
public void test() {
    AtomicInteger iCounter = new AtomicInteger(0);
    Mono<String> iValueMono = getMono(iCounter.incrementAndGet());

    Mono<String> resultMono = Mono.just("X")
        .flatMap(append(iValueMono))
        .flatMap(append(iValueMono));

    StepVerifier.create(resultMono)
        .consumeNextWith(result -> assertEquals(result, "X11"))
        .expectComplete()
        .verify();
}

private Mono<String> getMono(int x) {
    System.out.println("Called");
    return Mono.just(String.valueOf(x));
}

你觉得怎么样?有帮助吗?

裴英才
2023-03-14

使用Mono。cache()就是答案:

将此单声道转换为热源,并缓存最后发出的信号供进一步的订阅者使用。

使用它:

Mono<String> iValueMono = Mono.fromSupplier(() -> {
    int iValue = iCounter.getAndIncrement();
    System.out.println("iValueMono CALL: " + iValue);
    return String.valueOf(iValue);
}).cache();

只需给供应商打一次电话,即可达到预期效果。

 类似资料:
  • 我正在尝试使用SpringKafka将kafka与我的SpringBoot(v2.0.6版本)应用程序集成。现在我想要一个消费者和一个生产者。我让制作人工作得很好,我可以看到通过控制台消费者发送到主题的消息。我无法使用消费者代码,当Kafka主题中出现新消息时,它不会被调用。 这是我的Kafka配置类: 以下是我的pom依赖项: 以及消费者代码: 我正在我的计算机上运行kafka,正如我所说的——

  • 我在应用程序中为2个不同的包配置了Spring AOP来记录异常。每个封装有2种不同的配置: } method2中出现了一些异常,它调用了logExceptionXYZ方法,我们将它包装在一个泛型异常中,比如ExceptionXYZ,并进一步抛出它。 但在此之后,logExceptionABC方法也会被调用并抛出一个泛型异常,例如ExceptionABC。

  • 问题内容: 我经常在eclipse中使用重构->重命名功能,并且我也习惯于命名关联的单元测试TestedClassNameTest。但是,当我重命名测试过的类时,我一定不要忘记重命名我的unitTest。重命名已测试的类时,自动重命名我的单元测试非常有用。 我想创建一个可以完成任务的插件并不难,但也许甚至没有必要吗? 问题答案: 经过几次谷歌搜索和日食搜索后,似乎该功能尚不可用。 今天,Eclip

  • 我最近将我的应用程序配置为使用SpringCloudConfig和Github作为配置存储库。 Spring靴-2.1。1.发布 我的应用程序几乎使用了所有现成的东西。我刚刚在我有HikariCP自动配置在后台发挥神奇的作用。 我正在刷新我的应用程序使用这个作业,调用方法上的刷新endpoint。 一切似乎都很好,但每次刷新配置时,我都会看到以下日志。这些日志显示HikariCP池在每次刷新时都会

  • 我正在编写一个使用fire base来实现通知的应用程序。在我的Mainactive中,我有一个带有一些url的WebView,但问题是当用户单击通知时,我想在WebView中使用不同的url打开MainActiviy。我读了很多,我在意图中添加了一个捆绑包(在单击通知时打开Mainactive),它会生成所需的url。但是当我单击通知时,Mainactive会重新启动,我的意思是,它不会转到on