Kotlin 挂起函数在调用 java 时丢失 ReactiveSecurityContext

Posted

技术标签:

【中文标题】Kotlin 挂起函数在调用 java 时丢失 ReactiveSecurityContext【英文标题】:Kotlin Suspend Function Loses ReactiveSecurityContext when calling java 【发布时间】:2020-10-11 22:47:12 【问题描述】:

当我进入挂起函数时,上下文是存在的。这个函数是从一个也是挂起的控制器函数中调用的。

suspend fun search(searchRequest: String): String? 
    val context = ReactiveSecurityContextHolder.getContext().map 
      it
    .awaitFirstOrNull()
    log.info("The context here at the search is $context") 
    return someJava.something();

只要我进入 java 代码,上下文就在 java 中消失了。如果我回调 kotlin,安全上下文仍然消失。

public String something() 
  return someKotlin.something();


fun something(): String 
   val context = ReactiveSecurityContextHolder.getContext().map 
                    it
                 .awaitFirstOrNull()
   log.info("The context here is always null. Why? $context") 
 

知道如何解决这个问题吗?

【问题讨论】:

【参考方案1】:

ReactiveSecurityContextHolder.getContext() 不应该像全局变量/存储一样使用。

你应该得到它一次并对结果执行所有操作。

这里有相关答案https://***.com/a/51350355/6167844

【讨论】:

您应该能够根据需要多次访问此上下文。只要我不从 Kotlin 调用 java,它就可以正常工作。在为请求提供服务时,我可以随时访问。【参考方案2】:

出现这个问题是因为在 java 端有一些阻塞代码。一旦您阻塞,发布者链就会终止,并且您会丢失订阅者上下文。在后站,这是显而易见的。为了解决我的问题,我将安全上下文传递给 java 方法并存储在 threadlocal 对象中,以便稍后在 java 代码中访问它并在需要时传回 kotlin。这有点难看,但如果你无法修改 java 方法以返回发布者,那么这条路线是你唯一的选择

【讨论】:

以上是关于Kotlin 挂起函数在调用 java 时丢失 ReactiveSecurityContext的主要内容,如果未能解决你的问题,请参考以下文章

Kotlin 协程Flow 异步流 ① ( 以异步返回返回多个返回值 | 同步调用返回多个值的弊端 | 尝试在 sequence 中调用挂起函数返回多个返回值 | 协程中调用挂起函数返回集合 )

Kotlin 协程协程的挂起和恢复 ① ( 协程的挂起和恢复概念 | 协程的 suspend 挂起函数 )

Kotlin 协程协程的挂起和恢复 ① ( 协程的挂起和恢复概念 | 协程的 suspend 挂起函数 )

在 spring-boot 中使用 kotlin 挂起函数创建名称为“requestMappingHandlerMapping”的 bean 时出错

深入理解Kotlin协程如何将回调改写成挂起函数

如何在可组合函数回调中调用 Kotlin 协程?