如何拦截方法调用并调用它的原始版本?我成功拦截了它,但我失去了原来的呼叫。
这是我的代码
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()
,但它会导致拦截器被无限调用,直到它因堆栈溢出而崩溃。原始方法从未被调用。
您似乎正在尝试使用 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"))
}