2011-08-08 59 views
6

我在我的當前項目BeanBinding了很多工作,所以我有代碼看起來像......在運行時將方法名稱轉換爲bean名稱?

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

objAobjB是有一個setX()方法的類的實例。問題在於,如果我重構setXsetY那麼我需要搜索這些字符串屬性名稱。我意識到我可以爲屬性名稱創建靜態最終字符串,但如果我可以讓編譯器爲我完成這項工作,那就更好了。

理想情況下,我想什麼,能夠做的是...

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

這似乎這可以通過一些代碼的合成和/或方面是可行的。

+0

在黑暗中的完整鏡頭,但也許'returnBeanName'可以使用javassist來創建一個對象,它採用每個getter方法,修改它的返回類型爲String並返回屬性名稱?看起來很瘋狂,但寫起來很有趣。 – Jeremy

+0

@Jeremy:我想過你的建議,但爲了使Eclipse和其他重構工具正常工作,方法簽名必須保持不變,這對於制定者來說是一個真正的問題,因爲他們會產生空洞,並且也會因爲它們是「特殊的「 –

+0

我並不是說你應該修改bean本身。我的意思是你可以創建一個bean類的副本,方法名與你的bean完全相同,但是這些方法會返回屬性的名稱。 – Jeremy

回答

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

似乎那種瘋狂,但聽起來很有趣寫。

+0

Janino可能很適合這裏 –

+0

Nvm,janino是運行時只有 –

0

您可以使用instrumentation:使用ASM創建一個java agent以在編譯時訪問您的類並生成所需的類/接口/方法。這並不容易,你應該花時間學習Java工具,JVM字節碼和ASM庫,但是你可以用它來創造奇蹟。

+0

是的,我真的知道該怎麼做,但他們的問題在於,我現在需要將生成的類註冊回eclipse,以便它可以處理重構。我希望有人會說一些lib/plugin已經存在的原因之一。 –

0

我做了什麼像什麼傑里米Heiler在我的開源項目,Funcito,你可以browse the source code看到需要做使用字節碼操作,即使用了Javassist或CGLIB什麼爲例建議。

總體思路是,您使用Javassist或CGLIB的代碼增強器將感興趣的類作爲具有方法攔截器的子類進行代理。您攔截方法調用並記錄所調用方法的名稱,然後轉向並提取所調用的方法名稱並根據需要使用它。您使用的語義與Funcito使用語義非常相似,這與您作爲理想發佈的內容非常接近。