在运行时将方法名称转换为bean名称?

时间:2011-08-08 17:01:00

标签: java javabeans aop

我在当前的项目中使用BeanBinding很多,所以我的代码看起来像......

TypeA objA;
TypeB objB;
Bindings.createAutoBinding(UpdateStrategy.READ, 
    objA,   BeanProperty.create("X"),
    objB,   BeanProperty.create("X"))
    .bind();

objAobjB是具有setX()方法的类的实例。问题在于,如果我将setX重构为setY,那么我需要搜索这些字符串属性名称。我意识到我可以为属性名创建静态最终字符串,但是如果我能让编译器为我做的工作,那就更好了。

理想情况下,我希望能够做到的是......

TypeA obja;
TypeB objB;
Bindings.createAutoBinding(UpdateStrategy.READ, 
    objA,   BeanProperty.create( Magic.returnBeanName(TypeA.class).getX() ),
    objB,   BeanProperty.create( Magic.returnBeanName(TypeB.class).setX() )
    .bind();

通过一些代码综合和/或方面,这似乎是可能的。

3 个答案:

答案 0 :(得分:1)

在黑暗中完成一个完整的镜头,但也许returnBeanName可以使用javassist创建一个类似于bean的不同类,除了它将getter的返回类型修改为String并返回属性名称?

例如,如果您的bean看起来像这样:

public class Foo{
    private int x;

    public int getX(){
        return x;
    }

    public void setX(int x){
        this.x= x;
    }
}

然后动态创建一个不同的类,如下所示:

public class FooMeta{
    public String getX(){
        return "x";
    }
}

似乎有点疯狂,但写起来听起来很有趣。

答案 1 :(得分:0)

您可以使用instrumentation:使用java agent创建ASM以在编译时访问您的类并生成所需的类/接口/方法。这并不容易,你应该花时间去学习java检测,JVM字节码和ASM库,但你可以用它来创造奇迹。

答案 2 :(得分:0)

我做了类似Jeremy Heiler在我的开源项目Funcito中提出的建议,您可以browse the source code查看使用字节码操作需要做什么的示例,使用其中任何一个Javassist或CGLIB。

一般的想法是你使用Javassist或CGLIB的代码增强器来代理感兴趣的类作为具有方法拦截器的子类。您拦截方法调用并记录调用的方法的名称,然后转向并提取该调用的方法名称并根据需要使用它。您使用的语义与Funcito使用语义非常相似,它与您发布的理想值相近。