Java 在运行时将方法名转换为bean名?
在我当前的项目中,我经常使用BeanBinding,所以我的代码看起来像Java 在运行时将方法名转换为bean名?,java,javabeans,aop,Java,Javabeans,Aop,在我当前的项目中,我经常使用BeanBinding,所以我的代码看起来像 TypeA objA; TypeB objB; Bindings.createAutoBinding(UpdateStrategy.READ, objA, BeanProperty.create("X"), objB, BeanProperty.create("X")) .bind(); 其中objA和objB是具有setX()方法的类的实例。问题在于,如果我将setX重构为setY,那
TypeA objA;
TypeB objB;
Bindings.createAutoBinding(UpdateStrategy.READ,
objA, BeanProperty.create("X"),
objB, BeanProperty.create("X"))
.bind();
其中objA
和objB
是具有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();
这似乎可以通过一些代码合成和/或方面来实现。一个完整的暗中拍摄,但是可能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";
}
}
然后动态创建一个不同的类,如下所示:
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";
}
}
看起来有点疯狂,但写起来很有趣。您可以使用:创建一个using来在编译时访问类,并生成所需的类/接口/方法。这并不容易,你应该花时间学习java指令插入、JVM字节码和ASM库,但你可以用它创造奇迹。我做了一些类似Jeremy Heiler在我的开源项目中建议的事情,你可以看到一个使用字节码操作需要做什么的示例,使用Javassist或CGLIB
一般的想法是使用Javassist或CGLIB中的代码增强器将感兴趣的类代理为具有方法拦截器的子类。截取方法调用并记录所调用方法的名称,然后转身提取所调用的方法名称,并根据需要使用它。您使用的语义将非常类似于Funcito用法语义,这与您发布的理想语义非常接近。一个完整的暗中拍摄,但可能returnBeanName
可以使用javassist创建一个对象,该对象接受每个getter方法,将其返回类型修改为String并返回属性名?看起来有点疯狂,但写起来很有趣。@Jeremy:我考虑过你的建议,但为了让Eclipse和其他重构工具正常工作,方法签名必须保持不变,这对setter来说是一个真正的问题,因为它们会产生空洞,对final方法来说也是一个“特殊”的问题我不是说你应该修改bean本身。我的意思是你可以复制一个bean类,方法名与你的bean完全相同,但是这些方法返回属性名。@Jeremy:是的,但是当你改变它们返回的内容(它变成字符串)时,Eclipse会看到不同的结果。除非我遗漏了什么,我不是说“改变”。我将在回答中发布代码…是的,我实际上知道如何做,但问题在于,我现在需要将生成的类注册回eclipse,以便它能够处理重构。我希望有人会说一些库/插件已经存在的原因之一。