如何在租户上下文中正确使用 spring webclient

问题描述

我正在使用 Spring WebClient (org.springframework.web.reactive.function.client.WebClient) 来实现一些非阻塞行为。

        Mono<ClientResponse> clientResponse = 
            webClient
            .get(...).exchange();

        clientResponse.subscribe((response) -> {
             //--- unfortunately my tenant context is lost here !!! Someone kNows the right solution?
        });

然而,一旦响应到达,我的租户上下文就会丢失(当然,我们在一个新线程中)。

以下是有关如何在租户上下文中实现常见异步任务的文档:https://sap.github.io/cloud-sdk/docs/java/features/multi-tenancy/multi-tenancy-thread-context/

但是,我找不到如何使用 Spring webflux(使用 WebClient)保持租户上下文的推荐方法

解决方法

当且仅当您拥有控制权时,您才能将 SAP Cloud SDK 的 ThreadContext 转移到任何新线程:

  • 在创建新线程之前
  • 需要上下文的异步运行操作

我对 WebFlux 不太熟悉,但我会假设:

  • clientResponse.subscribe 在父线程中运行
  • 并且 lambda 是在异步线程中执行的

鉴于此,以下内容应将 ThreadContext 转移到 lambda 中:

ThreadContextExecutor executor = new ThreadContextExecutor();

clientResponse.subscribe((response) -> 
    executor.execute(() ->
       {
          // your code goes here,the ThreadContext should be available
       }
    )
);

您必须在新线程中运行操作的每个点都执行此操作。正如 Artem 指出的那样,目前 SDK 中没有任何功能可以自动实现相同的功能。


我认为也可以定义一个自定义的 ExecutorService,Spring 将使用它来创建和运行新的线程。在自定义执行器中,您可以为所有操作封装一次此包装逻辑。

,

SAP Cloud SDK API 支持 Spring Boot,目前不支持开箱即用的 Spring Webflux。如果在响应式 Spring 开发中使用 SDK API,您可能会看到各种错误。另一方面,正如 Matthias 所展示的那样,某些用例可能有变通方法。

我们考虑在未来添加 Spring WebFlux 支持。今年(2021 年)可能不会发生。