2011-06-03 99 views
4

我正在使用java 6註釋處理api。我按照以下優良的教程創建要顯示在生成時消息註釋處理器:使用Java註釋 - 生成代碼

http://kerebus.com/2011/02/using-java-6-processors-in-eclipse/

然而,在我的情況下,我有一個簡單類作爲這樣:

import java.lang.annotation.ElementType; 
import java.lang.annotation.Target; 

@Retention(RetentionPolicy.RUNTIME) 
@Target(value = ElementType.METHOD) 
public @interface Criteria { 
    String id(); 
    double width(); 
    double height(); 
} 

如您所見,上述註釋在運行時使用元註釋「保留」可供JVM使用。我使用另一個類的源代碼,這個「標準」進行註解的方法,像這樣:

@Criteria(id = "fooBar", 
    width = 22, 
    height = 10 
) 
public void fooStream() {  
    System.out.println("foo stream method"); 
} 

在運行時,我想包括在另一大類「fooStream」的方法,只有當是變量傳入匹配@Criteria註釋中元素的值,即'width'和'height'。我的問題是,如何在運行時將方法'fooStream'注入到另一個類中?這甚至有可能嗎?我不在尋找任何代碼示例,只是回答了上述兩個問題。另外,在頂部的鏈接中,有一個使用'JavaFileObject'和'Writer'實例生成代碼的示例,其中生成的代碼作爲字符串傳遞。

+0

你在問什麼,在運行時注入一個方法到另一個類中,而不是用java編程語言計算。 Java中沒有功能。你更想在JVM上創建你自己的新編程語言。 – Affe 2011-06-03 15:59:02

+1

你能解釋一下你想解決什麼問題嗎?你會如何在一個不知道它的課程中使用外星人的方法? – 2011-06-03 16:13:56

回答

0

如果您希望運行時修改您的,您可以使用自己的類加載器並攔截類加載,反思您想要的內容並使用asm庫而不是原始類生成新的字節碼。這不是非常棘手,但你必須確定你需要那個。

+1

我認爲這是我需要的方法。我已經閱讀了一些關於從本教程中獲取課程中包含的註釋的信息。我相信這是我可能需要的 - http://download.oracle.com/javase/6/docs/technotes/guides/language/annotations.html – Joeblackdev 2011-06-04 12:49:36

4

我不相信Java支持運行時類型突變,這意味着要修改給定類上的成員,您必須退回到編譯時預處理器或字節碼修改方案。

如果我能理解這個問題背後的「爲什麼」,那麼我可以指出你朝更好的方向發展,但同時,dynamic proxy classes可能會讓你到達想要的地方(JavaWorld article)。

從文檔:

的動態代理類是一類 實現在運行時,例如指定的接口 列表,通過 接口中的一個的 方法調用的類的一個實例 將被編碼並通過統一的 接口分派到 另一個對象。因此,可以使用動態代理類別 來爲接口列表創建類型安全的代理對象,而不需要代理類的預生成,例如使用編譯時工具 。上的動態代理 類的實例方法調用 被分派到在該實例的調用處理程序 單個 方法,以及它們與 java.lang.reflect.Method中對象 編碼識別是 調用的方法以及包含參數的Object 類型的數組。

下面是關於使用Spring注入基於自定義註釋動態代理體面tutorial。我認爲這可能與你之後的行爲最接近。

+0

問題背後的'爲什麼'是我會將上述代碼包含在jax-ws Web服務中。但是,如果滿足註釋中定義的條件,我只想觸發該方法。我不想使用大量'if/else'語句,因此註釋是我指定何時應該在運行時將webservice包含在方法中的一種方法。這是有道理的嗎? – Joeblackdev 2011-06-04 12:47:43

+1

是的。動態代理仍然是要走的路。編寫一個字節碼修改方案並不簡單,如果你只是想避免一些複雜的條件,這是一個巨大的矯枉過正。 – 2011-06-04 20:15:48