将字段添加到使用Javassist创建的Proxy类 [英] Add field to Proxy class created with Javassist
问题描述
我正在使用Javassist ProxyFactory创建一个Proxy类,代码如下:
I am creating a Proxy class using Javassist ProxyFactory with the following code:
ProxyFactory factory = new ProxyFactory();
factory.setSuperclass(entity.getClass());
factory.setInterfaces(new Class[] { MyCustomInterface.class });
.....
Class clazz = factory.createClass();
Object result = clazz.newInstance();
问题是我还需要在课程中添加一个字段。但是如果我做 CtClass proxy = ClassPool.getDefault()。get(clazz.getName());
它会给 NotFoundException
The problem is that I also need to add a field to the class. But if I do CtClass proxy = ClassPool.getDefault().get(clazz.getName());
it gaves a NotFoundException
如何添加使用createClass创建的类的字段?有没有更好的方法来做我想做的事情?
How can I add a field the class created with createClass? Is there a better way to do what I am trying to do?
推荐答案
这取决于你对我评论的回复。
This is based in your reply to my comment.
你确实可以使用 MyCustomInterface
和你的proxyClass创建一个 mixin 。但是你仍然需要从代理类转换为 MyCustomInterface
才能调用方法。
You can indeed use MyCustomInterface
and your proxyClass to create sort of a mixin in Java. But you'll still have to cast from proxy class to MyCustomInterface
to be able to call the methods.
让我们开始使用。
首先,您已经创建了代理:
First you create your proxy has you already were doing:
// this is the code you've already posted
ProxyFactory factory = new ProxyFactory();
factory.setSuperclass(entity.getClass());
factory.setInterfaces(new Class[] { MyCustomInterface.class });
方法处理程序:做魔法
Javassist代理允许您添加 MethodHandler 。它基本上是一个常规Java代理中的InvocationHandler,这意味着它可以作为一个方法拦截器。
Method handler: Doing the magic
Javassist proxies allow you to add a MethodHandler. It basically acts has a an InvocationHandler would in a regular Java Proxy, that means it works as a method interceptor.
方法处理程序将是你的mixin!首先,您创建一个新的MethodHandler,其中包含您实际要添加到类中的自定义字段,以及您已开始代理的实体对象:
The method handler will be your mixin! First you create a new MethodHandler with the custom field you actually want to add to the class, along with the entity object you've started proxying:
public class CustomMethodHandler implements MethodHandler {
private MyEntity objectBeingProxied;
private MyFieldType myCustomField;
public CustomMethodHandler(MyEntity entity) {
this.objectBeingProxied = entity;
}
// code here with the implementation of MyCustomInterface
// handling the entity and your customField
public Object invoke(Object self, Method method, Method proceed, Object[] args) throws Throwable {
String methodName = method.getName();
if(methodNameFromMyCustomInterface(methodName)) {
// handle methodCall internally:
// you can either do it by reflection
// or if needed if/then/else to dispatch
// to the correct method (*)
}else {
// it's just a method from entity let them
// go. Notice we're using proceed not method!
proceed.invoke(objectBeingProxied,args);
}
}
}
(*)请注意,即使如果我在评论中说在内部处理调用,你可以在另一个不是你的方法处理程序的地方实现接口实现,只需从这里调用它。
(*) Notice that even if I say in the comment to handle the call internally you can have the interface implementation in another place that isn't your method handler and just call it from here.
ProxyFactory factory = new ProxyFactory();
factory.setSuperclass(entity.getClass());
factory.setInterfaces(new Class[] { MyCustomInterface.class });
Class cls = factory.createClass();
// bind your newly methodHandler to your proxy
((javassist.util.proxy.Proxy) cls).setHandler(new CustomMethodHandler(entity));
EntityClass proxyEntity = cls.newInstance();
您现在应该可以执行((MyCustomInterface)proxyEntity).someMethodFromTheInterface ()
并让它由你的 CustomMethodHandler处理
You should now be able to do ((MyCustomInterface)proxyEntity).someMethodFromTheInterface()
and let it be handled by your CustomMethodHandler
- 使用javassist中的Proxy Factory创建代理
- 您可以创建自己的MethodHandler类,可以接收代理实体和您要操作的字段
- 将methodHandler绑定到代理,以便委托接口实现
请记住,这些方法并不完美,除非您首先创建代理,否则Entity类中的代码无法引用接口之一。
Keep in mind that these approach isn't perfect, being one of the short comings the code in Entity class cannot refer to the interface unless you first create the proxy.
如果您对此不太清楚,请发表评论,我会尽力澄清您。
If anything wasn't very clear for you, just comment and I'll do my best to clarify you.
这篇关于将字段添加到使用Javassist创建的Proxy类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!