将字段添加到使用Javassist创建的Proxy类 [英] Add field to Proxy class created with Javassist

查看:159
本文介绍了将字段添加到使用Javassist创建的Proxy类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆