问题
I am using Byte-Buddy to dynamically generate implementations of Java interface methods, and to delegate the calls to these methods to a single method of an existing proxy object.
The first version was inspired by How to create a dynamic proxy using ByteBuddy
It uses a Reflection InvocationHandler
i.e. the concrete proxy class:
- implements the interface
InvocationHandler
- overrides the method
invoke()
This works fine.
Then re-reading the Byte-Buddy readme on Github I discovered an alternative version using MethodDelegation
to a "GeneralInterceptor".
i.e. the concrete proxy class:
- has a method marked with the
RuntimeType
annotation.
This also works fine!
The code snippets below demonstrate both techniques.
Class<? extends Object> clazz = new ByteBuddy()
.subclass(serviceSuperClass)
.name(className)
// use a Reflection InvocationHander for the methods of serviceInterfaceOne
.implement(serviceInterfaceOne)
.defineField(invocationHandler, MyProxy.class, Visibility.PUBLIC)
.method(isDeclaredBy(serviceInterfaceOne))
.intercept(InvocationHandlerAdapter.toField(invocationHandler))
// use a Byte-Buddy "GeneralInterceptor" for the methods of serviceInterfaceTwo
.implement(serviceInterfaceTwo)
.defineField(generalInterceptor, MyProxy.class, Visibility.PUBLIC)
.method(isDeclaredBy(serviceInterfaceTwo))
.intercept(MethodDelegation.toField(generalInterceptor))
//
.make ()
.load(classLoader)
.getLoaded();
public class MyProxy implements InvocationHandler {
@Override
public Object invoke(Object serviceImpl, Method method, Object[] args) throws Throwable {
return null;
}
@RuntimeType
public Object intercept(@AllArguments Object[] allArguments,
@Origin Method method) {
return null;
}
}
From a high-level point-of-view both techniques allow me to do the same thing:
i.e. intercept the given dynamically created methods to an existing concrete method.
Both solutions are elegant, and the amount of code required is similar.
The question is: is there any reason to prefer the one over the other? e.g. Performance? Functionality?
回答1:
In this form of usage, there is no real difference other than the delegation can be wired to any (static or non-static) method whereas the invocation handler adapter only bridges implementations for Java's proxy API. It is mainly meant if you already implemented such proxy handlers and want to reuse them with Byte Buddy.
Byte Buddy's handler allows for more flexibility then the handler API which improves performance since you can for example avoid the array boxing if you know what arguments to expect. It also allows for different mechanisms like invoking a default method implementation that the invocation handler API does not support.
来源:https://stackoverflow.com/questions/60317919/byte-buddy-method-interception-invocationhandler-vs-methoddelegation-to-general