在Spring MVC中配置默认Kotlin协程上下文 [英] Configure default Kotlin coroutine context in Spring MVC
本文介绍了在Spring MVC中配置默认Kotlin协程上下文的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我需要为Spring MVC中的所有请求配置默认协程上下文。例如MDCContext
(问题类似于this,但针对的是MVC而不是WebFlux)。
我尝试的内容
- 挂钩到Spring-协程代码是here,但无法更改默认行为(需要更改
InvocableHandlerMethod.doInvoke
实现) - 使用AOP-AOP和协程不使用play well together
有什么想法吗?
推荐答案
这似乎起作用了:
@Configuration
class ContextConfig: WebMvcRegistrations {
override fun getRequestMappingHandlerAdapter(): RequestMappingHandlerAdapter {
return object: RequestMappingHandlerAdapter() {
override fun createInvocableHandlerMethod(handlerMethod: HandlerMethod): ServletInvocableHandlerMethod {
return object : ServletInvocableHandlerMethod(handlerMethod) {
override fun doInvoke(vararg args: Any?): Any? {
val method = bridgedMethod
ReflectionUtils.makeAccessible(method)
if (KotlinDetector.isSuspendingFunction(method)) {
// Exception handling skipped for brevity, copy it from super.doInvoke()
return invokeSuspendingFunctionX(method, bean, *args)
}
return super.doInvoke(*args)
}
/**
* Copied from CoroutinesUtils in order to be able to set CoroutineContext
*/
@Suppress("UNCHECKED_CAST")
private fun invokeSuspendingFunctionX(method: Method, target: Any, vararg args: Any?): Publisher<*> {
val function = method.kotlinFunction!!
val mono = mono(YOUR_CONTEXT_HERE) {
function.callSuspend(target, *args.sliceArray(0..(args.size-2))).let { if (it == Unit) null else it }
}.onErrorMap(InvocationTargetException::class.java) { it.targetException }
return if (function.returnType.classifier == Flow::class) {
mono.flatMapMany { (it as Flow<Any>).asFlux() }
}
else {
mono
}
}
}
}
}
}
}
这篇关于在Spring MVC中配置默认Kotlin协程上下文的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文