如何拦截方法调用并调用它的原始版本?

问题描述 投票:0回答:1

如何拦截方法调用并调用它的原始版本?我成功拦截了它,但我失去了原来的呼叫。

这是我的代码

public class TargetClass {

    public String opts(String param) {
        return param.toLowerCase();
    }
}

public class MyInterceptor {

    @RuntimeType
    public static void intercept(
            @Origin(cache = false) Method method, @This TargetClass that, @RuntimeType @AllArguments Object[] allArguments) throws InvocationTargetException, IllegalAccessException {

        System.out.println(that);
    }
}

fun main(args: Array<String>) {

    ByteBuddyAgent.install();

    val byteBuddy = ByteBuddy()


    val classLoader = ClassLoader.getSystemClassLoader()

    val reloadingStrategy = ClassReloadingStrategy.fromInstalledAgent()


    byteBuddy
        .redefine(TargetClass::class.java)
        .method(ElementMatchers.named<NamedElement>("opts"))
        .intercept(MethodDelegation.to(MyInterceptor::class.java))
//        .intercept(MethodCall.invokeSelf().withAllArguments().andThen(MethodDelegation.to(interceptor)))
        .make()
        .load<ClassLoader>(classLoader, reloadingStrategy)

    val test = TargetClass()
    println(test.opts("TEST"))
}

我尝试使用

MethodCall.invokeSelf().withAllArguments()
,但它会导致拦截器被无限调用,直到它因堆栈溢出而崩溃。原始方法从未被调用。

java byte-buddy
1个回答
0
投票

您似乎正在尝试使用 Byte Buddy 拦截方法调用并在拦截器中调用原始方法。但是,您提供的代码缺少实际调用原始方法的部分。

以下是如何修改拦截器以拦截方法调用并调用原始方法:

import net.bytebuddy.ByteBuddy
import net.bytebuddy.agent.ByteBuddyAgent
import net.bytebuddy.dynamic.loading.ClassReloadingStrategy
import net.bytebuddy.implementation.MethodCall
import net.bytebuddy.implementation.MethodDelegation
import net.bytebuddy.matcher.ElementMatchers
import java.lang.reflect.Method
import java.lang.reflect.InvocationTargetException

class TargetClass {

    fun opts(param: String): String {
        return param.toLowerCase()
    }
}

class MyInterceptor {

    companion object {
        @JvmStatic
        fun intercept(
            @Origin(cache = false) method: Method,
            @This target: Any,
            @AllArguments args: Array<Any>
        ): Any {
            try {
                // You can print some information or do other pre-processing here
                println("Interceptor is called")

                // Invoke the original method
                val result = MethodCall.invoke(method).on(target).withArguments(*args).withoutArguments().execute()

                // You can do post-processing here if needed

                return result
            } catch (e: Exception) {
                // Handle exceptions if needed
                e.printStackTrace()
                throw e
            }
        }
    }
}

fun main() {
    ByteBuddyAgent.install()

    val byteBuddy = ByteBuddy()

    val classLoader = ClassLoader.getSystemClassLoader()

    val reloadingStrategy = ClassReloadingStrategy.fromInstalledAgent()

    byteBuddy
        .redefine(TargetClass::class.java)
        .method(ElementMatchers.named("opts"))
        .intercept(MethodDelegation.to(MyInterceptor::class.java))
        .make()
        .load<ClassLoader>(classLoader, reloadingStrategy)

    val test = TargetClass()
    println(test.opts("TEST"))
}
© www.soinside.com 2019 - 2024. All rights reserved.