Динамический прокси для методов приостановки? - PullRequest
0 голосов
/ 16 ноября 2018

Это мой интерфейс:

interface BlogService {
    suspend fun tag() : JsonObject
}

Возможно ли создать динамический прокси для метода suspend и запустить сопрограмму внутри?Я не могу использовать "Proxy.newProxyInstance" из jdk, потому что я получаю ошибку компиляции (функция приостановки должна быть запущена из другой функции приостановки)

1 Ответ

0 голосов
/ 03 января 2019

У меня была такая же проблема. И я думаю, что ответ - да. Вот что я понял.

Следующий интерфейс

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

компилируется в

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

после компиляции нет никакой разницы между нормальной функцией и приостановкой функция, за исключением того, что последний имеет дополнительный аргумент типа Continuation. Просто верните COROUTINE_SUSPENDED в делегированном InvocationHandler.invoke если вы действительно хотите, чтобы он был заменен.

Вот пример создания экземпляра ISerivce через динамический прокси Java. объект 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
}

Я считаю, что этот фрагмент кода достаточно прост и не требует объяснений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...