问题描述
我正在使用 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 年)可能不会发生。