如何使用ByteBuddy获得类的动态代理



我想使用动态代理使用Proxy.newProxyInstance生成的类(Swagger),这些都没有实现接口,这给我带来了ByteBuddy,使用它应该允许我构建Proxy.newProxyInstance所需的接口。
I got so far:

Class<?> restClass = RestServiceApi.class;
Builder<?> builder = byteBuddy.makeInterface().merge(Visibility.PUBLIC).name(restClass.getName() + "I");
for (Method method : restClass.getMethods()) {

builder = builder.defineMethod(method.getName(),HOW_TO_DO_THIS);

}
Class<?> restInterface = builder.make().load(this.getClass().getClassLoader()).getLoaded();
Class<?>[] proxyInterfaces = new Class<?>[] { restInterface };
// TODO create manipulatedRestServiceApiThatImplementsRestInterfaceI
asyncServiceProxy = new AsynchronousServiceProxy<>(RestServiceApi.class, errorHandler, guiBlockingListener);
ctrAsyncService = (manipulatedRestServiceApiThatImplementsRestInterfaceI) Proxy.newProxyInstance(RestServiceApi.class.getClassLoader(), proxyInterfaces, asyncServiceProxy);

即使可以弄清楚,如何编写定义每个方法所需的代码,我得到的感觉,我没有以正确的方式这样做,我要编写大量的代码来将Method的反射信息转换为ByteBudd需要的任何内容,我怀疑有一个更容易的方法来构建这个接口类。

如果有人能给我指个正确的方向,我将非常感激。

事实证明我的预感是正确的(我从错误的角度出发了),我应该更广泛地问这个问题。我实际需要(但没有问)的是一种构建动态代理的解决方案,在这种情况下,您没有服务接口,只有服务类。
使用服务接口,您可以使用java.lang.reflect.Proxy构建动态服务代理:

MyInvocationHandler<ServiceInterface> serviceProxy = new MyInvocationHandler<>();
proxiedService = (ServiceInterface) Proxy.newProxyInstance(ServiceInterface.class.getClassLoader(), new Class[] { ServiceInterface.class }, serviceProxy);
proxiedService.methodOfServiceInterface();

语句proxiedService.methodOfServiceInterface()和将调用方法MyInvocationHandler.invoke(Object proxy, final Method method, final Object[] arguments),该方法可以执行实际方法所需的任何操作(例如通过远程方法调用)。
此方法可以很好地调用具有接口的ejb或SOAP服务,但会中断服务类。因此,我实际上需要的是一种算法来构建一个动态服务代理,它适用于服务接口服务类。
使用ByteBuddy构建动态服务代理实际上非常简单。下面的泛型方法实现了所需的算法:

/**
* Creates a service proxy to call methods of the service class/interface.
*
* @param <T>                     type of service class or interface
* @param serviceClassOrInterface service class or interface
* @param serviceProxy            the service proxy
* @return service proxy
*/
public static <T> T createDynamicProxy(Class<T> serviceClassOrInterface, MyInvocationHandler<T> serviceProxy) {
try {
return new ByteBuddy()
.subclass(serviceClassOrInterface)
.method(isDeclaredBy(serviceClassOrInterface))
.intercept(InvocationHandlerAdapter.of(serviceProxy))
.make()
.load(serviceClassOrInterface.getClassLoader())
.getLoaded().getConstructor().newInstance();
} catch (Exception exception) {
throw new RuntimeException("Error creating dynamic proxy of " + serviceClassOrInterface.getName(), exception);
}
}

可以这样使用:

MyInvocationHandler<ServiceInterface> serviceProxy = new MyInvocationHandler<>();
proxiedService = createDynamicProxy(serviceInterface, serviceProxy);

您可以简单地应用:

builder = builder.define(method).intercept(MethodDelegation.to(YourDelegation.class));

MethodDelegation在Javadoc中有广泛的文档记录,为了最简单的解决方案,您可能需要通过它的签名来解析被调用的方法,然后使用反射来调用它。

最新更新