gpt4 book ai didi

java - 将字段添加到使用 Javassist 创建的 Proxy 类

转载 作者:行者123 更新时间:2023-12-03 02:49:22 25 4
gpt4 key购买 nike

我正在使用 Javassist ProxyFactory 和以下代码创建一个 Proxy 类:

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

如何添加使用 createClass 创建的类的字段?有没有更好的方法来完成我想做的事情?

最佳答案

这是基于您对我的评论的回复。

您确实可以使用 MyCustomInterface 和您的 proxyClass 来创建某种 mixin在 java 。但您仍然需要从代理类转换为 MyCustomInterface 才能调用这些方法。

让我们开始吧。

创建您的代理

首先创建代理,您已经在这样做:

 // 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 代理中具有 InvocableHandler 的作用,这意味着它作为方法拦截器工作。

方法处理程序将是你的 mixin!首先,您使用您实际想要添加到类中的自定义字段以及您已开始代理的实体对象创建一个新的 MethodHandler:

  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);
}
}
}

(*) 请注意,即使我在注释中说要在内部处理调用,您也可以在不是您的方法处理程序的另一个地方实现接口(interface)实现,然后从这里调用它。

将所有内容整合在一起

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 处理

总结

  • 您使用 javassist 中的 Proxy Factory 创建代理
  • 您创建自己的 MethodHandler 类,该类可以接收您的代理实体和您要操作的字段
  • 将 methodHandler 绑定(bind)到代理,以便可以委托(delegate)接口(interface)实现

请记住,这些方法并不完美,这是实体类中的代码无法引用接口(interface)的缺点之一,除非您首先创建代理。

如果您有任何不清楚的地方,请发表评论,我会尽力为您澄清。

关于java - 将字段添加到使用 Javassist 创建的 Proxy 类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20460262/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com