暂停方法的动态代理?

时间:2018-11-16 19:48:53

标签: kotlin

这是我的界面:

interface BlogService {
    suspend fun tag() : JsonObject
}

是否可以为suspend方法创建动态代理并在其中运行协程? 我无法使用jdk中的“ Proxy.newProxyInstance”,因为我收到了编译错误(暂停功能应从另一个暂停功能运行)

1 个答案:

答案 0 :(得分:1)

我有同样的问题。我认为答案是肯定的。这就是我的想法。

以下界面

interface IService {
    suspend fun hello(arg: String): Int
}

被编译成这个

interface IService {
    fun hello(var1: String, var2: Continuation<Int>) : Any
}

编译后,正常函数和挂起之间没有区别 函数,除了后者具有类型的附加参数 Continuation。只需在委托中返回COROUTINE_SUSPENDED InvocationHandler.invoke(如果您确实希望将其暂停)。

这是通过Java动态代理创建ISerivce实例的示例 设施Proxy.newProxyInstance

import java.lang.reflect.InvocationHandler
import java.lang.reflect.Proxy
import kotlin.coroutines.Continuation
import kotlin.coroutines.intrinsics.COROUTINE_SUSPENDED
import kotlin.coroutines.resume

fun getServiceDynamic(): IService {
    val proxy = InvocationHandler { _, method, args ->
        val lastArg = args?.lastOrNull()
        if (lastArg is Continuation<*>) {
            val cont = lastArg as Continuation<Int>
            val argsButLast = args.take(args.size - 1)
            doSomethingWith(method, argsButLast, onComplete = { result: Int ->
                cont.resume(result)
            })
            COROUTINE_SUSPENDED
        } else {
            0
        }
    }
    return Proxy.newProxyInstance(
        proxy.javaClass.classLoader,
        arrayOf(IService::class.java),
        proxy
    ) as IService
}

我相信此代码段非常简单且易于理解。