在 Spring Webflux 中结合非阻塞和阻塞调用并返回结果

Posted

技术标签:

【中文标题】在 Spring Webflux 中结合非阻塞和阻塞调用并返回结果【英文标题】:Combining non-blocking and blocking calls and returning the results in Spring Webflux 【发布时间】:2020-10-09 05:28:06 【问题描述】:

我正在使用 Spring Webflux 和 Spring Boot 2,我的场景是这样的:

控制器

@GetMapping(path="/products")
public List<Products> getProducts()
 return serviceObj.getProducts();

服务类

public List<Products> getProducts()
List<Products> products = null;
  //Call 1 -> to repository class method returning Flux<Products>
repositoryObj.getProductsFlux();
  //Call 2 -> To repository class method returning List<Products>
repositoryObj.getProductsNormal();
  //Concat results from Call 1 & Call 2 and return List<Products>
return products;

如何在返回之前连接 Flux 和正常产品列表中的结果? 没有响应式控制器是否可能?

附:我不想对从 Call 1 获得的结果调用 .block() 和 CompleteableFuture

【问题讨论】:

没有阻塞就无法获得Future。您必须使用.block() 才能获得结果。我已经在 Webflux 上工作了一年,所以我想说永远不要混合阻塞和非阻塞,这是一个非常糟糕的设计。在这种情况下,您应该修改您对 Reactor 核心的概念。 【参考方案1】:

如果您想从该方法返回List&lt;Products&gt;,则没有.block() 方式就无法做到这一点。

您应该合并结果并从此方法返回Flux&lt;Products&gt; 以保持反应式方法。您可以使用mergeWithconcatWith

示例:

public Flux<Products> getProducts()
    List<Products> productsNonFlux = repositoryObj.getProductsNormal();
    Flux<Products> productsFlux = repositoryObj.getProductsFlux();
    return productsFlux.mergeWith(Flux.fromIterable(productsNonFlux));

重要!

请记住,如果您的 repositoryObj.getProductsNormal() 正在使用 JDBC,那么此调用将阻塞线程池。

在这种情况下,请查看: Execute blocking JDBC call in Spring Webflux

【讨论】:

以上是关于在 Spring Webflux 中结合非阻塞和阻塞调用并返回结果的主要内容,如果未能解决你的问题,请参考以下文章

Spring WebFlux 入门

深入剖析 Spring WebFlux

Spring Reactive Programming with Webflux - 多个操作作为非阻塞流

是时候考虑Spring非阻塞编程模式?R2DBC pk JDBC 和 WebFlux pk Web MVC 评测数据

Spring Boot webflux介绍

webFlux 学习