这是基于您对我的评论的回复。
您确实可以使用MyCustomInterface 和您的proxyClass 在Java 中创建一种mixin。但是您仍然必须从代理类转换为 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 代理中具有 InvocationHandler,这意味着它可以作为方法拦截器。
方法处理程序将是您的混音!首先,您创建一个新的 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);
}
}
}
(*) 请注意,即使我在注释中说要在内部处理调用,您也可以将接口实现放在不是您的方法处理程序的另一个地方,然后从这里调用它。
把所有东西放在一起
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 中的代理工厂创建代理
- 您创建自己的 MethodHandler 类,该类可以接收您的代理实体和您要操作的字段
- 您将 methodHandler 绑定到您的代理,以便您可以委托接口实现
请记住,这些方法并不完美,这是 Entity 类中的代码无法引用接口的缺点之一,除非您首先创建代理。
如果您有什么不清楚的地方,请发表评论,我会尽力为您澄清。