首页 > 解决方案 > 如何在租户上下文中正确使用 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编辑:SAP Cloud SDK在操作结束时销毁 a 。这样做是为了防止它泄漏,例如在重新使用线程时。

如果:

  • 上下文被传递给异步操作
  • 但是“父”操作是在异步操作开始之前完成的

ThreadContext异步操作中将不可用。这就是使用WebClient.

这不适用于自定义属性,SDK 不会清除它们。但这也意味着您必须自己清除它们以确保在重新使用线程时它们不会泄漏。

在这种情况下,我建议不要使用 SDK 的多租户功能。不过,我将把下面的答案留在上下文中。


当且仅当您具有控制权时,您可以将 SAP Cloud SDK 的 ThreadContext 传输到任何新线程:

  • 在创建新线程之前
  • 需要上下文的将异步运行的操作
  • 编辑:父线程(上下文)仍然存在

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

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

鉴于此,以下内容应将ThreadContextlambda 中的存在转移:

ThreadContextExecutor executor = new ThreadContextExecutor();

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

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


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


推荐阅读