2013-04-30 59 views
0

是否可以在加載時編織時使用AspectJ對編譯類文件執行類型間聲明?編譯類文件的類型間聲明

舉個例子:我編譯了一些Groovy代碼,並想用IDT添加字段或方法。

回答

1

更新:

哦,我的天啊,你不需要反射來訪問成員或執行方法。 Eclipse在編輯器中顯示錯誤,但您可能會忽略它們,代碼編譯並運行良好。所以,一方面是確實更strightforward簡單:

public aspect LTWAspect { 
    public static String Application.staticField = "value of static field"; 
    public String Application.normalField = "value of normal field"; 

    public void Application.myMethod() { 
     System.out.println(normalField); 
    } 

    void around() : execution(void Application.main(..)) { 
     System.out.println("around before"); 
     proceed(); 
     System.out.println("around after"); 
     System.out.println(Application.staticField); 
     new Application().myMethod(); 
    } 
} 

原來的答覆:

是的,但你有一個雞和蛋的問題出現,即你不能只是參考LTW方面代碼中新引入的字段沒有反射。 (最後一句不對,請參閱上面的更新。)另外,爲了使LTW方面能夠編譯,需要在項目的構建路徑上編織類,以便能夠引用它們。例如:

Java項目

public class Application { 
    public static void main(String[] args) { 
     System.out.println("main"); 
    } 
} 

AspectJ項目

import org.aspectj.lang.SoftException; 

public aspect LTWAspect { 
    public static String Application.staticField = "value of static field"; 
    public String Application.normalField = "value of normal field"; 

    public void Application.myMethod() { 
     try { 
      System.out.println(Application.class.getDeclaredField("normalField").get(this)); 
     } catch (Exception e) { 
      throw new SoftException(e); 
     } 
    } 

    void around() : execution(void Application.main(..)) { 
     System.out.println("around before"); 
     proceed(); 
     System.out.println("around after"); 
     try { 
      System.out.println(Application.class.getDeclaredField("staticField").get(null)); 
      Application.class.getDeclaredMethod("myMethod", null).invoke(new Application()); 
     } catch (Exception e) { 
      throw new SoftException(e); 
     } 
    } 
} 

所以,如在Eclipse中,您需要將Java項目放在AspectJ項目的構建路徑下的「Projects」下,因爲只有這樣它才能看到要聲明其成員的Java類Application。編譯之後,您只需啓動Java項目並在方面項目上執行LTW(不要忘記參考LTWAspectaop-ajc.xml)。

在我上面的例子中,我聲明瞭一個靜態成員,一個非靜態(「普通」)成員和一個非靜態方法。我的建議打印靜態成員,並通過反射調用非靜態方法。非靜態方法然後通過反射再次打印非靜態成員。這並不好,但它的工作原理和證明ITD與LTW結合是可能的。可能有更優雅的方式,但如果是這樣,我不知道它。 (更新:有一個更優雅的方式:只需忽略的Eclipse IDE標註錯誤,見上文)

程序輸出

around before 
main 
around after 
value of static field 
value of normal field 
+0

謝謝。這看起來不錯。但是你提到你必須把Java項目放在AspectJ項目的構建路徑上。使用Groovy,您只能獲得編譯後的類文件。是否也可以導入這些類文件並使用它們? – Thorben 2013-05-04 15:49:13

+0

當然。我不使用Groovy,但它編譯爲JVM類文件,所以它應該可以工作。 – kriegaex 2013-05-05 01:22:24

+0

請查看我的更新。你不需要反思! – kriegaex 2013-05-05 12:47:15