在Byte-Buddy中,你可以使用InvocationHandler或GeneralInterceptor来拦截方法。下面是使用这两种方式的代码示例:
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.implementation.MethodDelegation;
import net.bytebuddy.implementation.bind.annotation.AllArguments;
import net.bytebuddy.implementation.bind.annotation.RuntimeType;
import net.bytebuddy.implementation.bind.annotation.SuperCall;
import net.bytebuddy.implementation.bind.annotation.This;
import java.lang.reflect.Method;
import java.util.concurrent.Callable;
public class InvocationHandlerExample {
public static class MyInvocationHandler {
@RuntimeType
public static Object intercept(@AllArguments Object[] args,
@SuperCall Callable> callable,
@This Object target,
@Origin Method method) throws Exception {
System.out.println("Before method: " + method.getName());
// 在方法调用前执行额外的逻辑
Object result = callable.call(); // 调用原始方法
// 在方法调用后执行额外的逻辑
System.out.println("After method: " + method.getName());
return result;
}
}
public static void main(String[] args) throws IllegalAccessException, InstantiationException {
Class> dynamicType = new ByteBuddy()
.subclass(Object.class)
.method(any())
.intercept(MethodDelegation.to(MyInvocationHandler.class))
.make()
.load(InvocationHandlerExample.class.getClassLoader())
.getLoaded();
try {
Object instance = dynamicType.newInstance();
instance.toString();
instance.hashCode();
} catch (Exception e) {
e.printStackTrace();
}
}
}
在上面的示例中,我们创建了一个InvocationHandler类MyInvocationHandler
,它的intercept
方法将在方法调用前后执行。使用Byte-Buddy的MethodDelegation
将方法委托给该InvocationHandler。
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.dynamic.DynamicType;
import net.bytebuddy.implementation.MethodDelegation;
import net.bytebuddy.implementation.bind.annotation.AllArguments;
import net.bytebuddy.implementation.bind.annotation.RuntimeType;
import net.bytebuddy.implementation.bind.annotation.SuperCall;
import net.bytebuddy.implementation.bind.annotation.This;
import net.bytebuddy.matcher.ElementMatchers;
import java.lang.reflect.Method;
import java.util.concurrent.Callable;
public class GeneralInterceptorExample {
public static class MyInterceptor {
@RuntimeType
public static Object intercept(@AllArguments Object[] args,
@SuperCall Callable> callable,
@This Object target,
@Origin Method method) throws Exception {
System.out.println("Before method: " + method.getName());
// 在方法调用前执行额外的逻辑
Object result = callable.call(); // 调用原始方法
// 在方法调用后执行额外的逻辑
System.out.println("After method: " + method.getName());
return result;
}
}
public static void main(String[] args) throws IllegalAccessException, InstantiationException {
DynamicType.Unloaded> dynamicType = new ByteBuddy()
.subclass(Object.class)
.method(ElementMatchers.any())
.intercept(MethodDelegation.withDefaultConfiguration()
.withBinders(MyInterceptor.Binder.INSTANCE)
.to(new MyInterceptor()))
.make();
try {
Class> loaded = dynamicType.load(GeneralInterceptorExample.class.getClassLoader())
.getLoaded();
Object instance = loaded.newInstance();
instance.toString();
instance.hashCode();
} catch (Exception e) {
e.printStackTrace();
}
}
}
在上面的示例中,我们创建了一个GeneralInterceptor类MyInterceptor
,它的intercept
方法将在方法调用前后执行。使用Byte-Buddy的MethodDelegation
和withBinders
将方法委托给该GeneralInterceptor。
这两种方式的区别在于InvocationHandler是通过反射调用原始方法,而GeneralInterceptor是通过Callable.call()调用原始方法。根据你的需要选择适合的方式。