2012-02-24 61 views
1

我正在嘗試學習如何在Java中編寫自定義註釋。爲了學習的目的,我決定嘗試創建一個使用註釋爲類提供可用字段的註釋,例如:注入但不是必需的,作爲單例讓它更簡單(我認爲),但這也是受歡迎的。注入另一個對象的Java自定義註釋

================================= CLASS 1 ========= ========================

import java.lang.annotation.ElementType; 
import java.lang.annotation.Inherited; 
import java.lang.annotation.Retention; 
import java.lang.annotation.RetentionPolicy; 
import java.lang.annotation.Target; 


@Target(ElementType.METHOD) 
@Retention(RetentionPolicy.RUNTIME) 
@Inherited 
public @interface AutoInject { 

} 

=================== ============== CLASS 2 ================================ =

// The class to be injected in Main.java 
public class TestClass0 { 

    void printSomething(){ 
     System.out.println("PrintSomething: TestClass0"); 
    } 

} 

================================= CLASS 3 ===== ============================

import java.lang.annotation.Annotation; 
import java.lang.reflect.Field; 

public class Main { 

    TestClass0 ts0; 
    // Injecting here!! 
    @AutoInject 
    public TestClass0 getTso() { 
     return ts0; 
    } 
    public void setTso(TestClass0 ts) { 
     ts0 = ts; 
    } 

    public static void main(String[] args) { 
     performAnnotationScanOnClass (Main.class); 

     // Create instance 
     Main main = new Main();  
     main.getTso().printSomething(); 

    } 

    public static void performAnnotationScanOnClass(Class<?> clazz) { 
     Field[] fields = clazz.getDeclaredFields(); 

     for (Field field : fields) { 

      Annotation[] annotations = field.getAnnotations(); 
      for (Annotation annotation : annotations) { 

       if (annotation instanceof AutoInject) { 
        AutoInject autoInject = (AutoInject) annotation; 

//      if (field.get(...) == null) 
//       field.set(... , value) 
       } 

      } 

     } 
    } 

} 

正如你可以在靜態void main()中看到的...我試圖調用TestClass0中的方法,期望它可用。我知道上述內容從接近完成開始就很長,但我剛開始學習註釋並希望得到您的指導。

我們如何能火的一段代碼,即initializez物業無論是在或當get方法被調用。使用註釋。我想而不改變調用方法。

謝謝!

+0

你認爲你的測試註釋,但你真的重塑CDI。不要...重塑...輪子。 – Perception 2012-02-24 15:52:00

+6

我沒有重新發明任何東西。我正在努力學習其他人如何實現和創造,而不是使用它。你瞭解區別?它的教育目的。 – momomo 2012-02-24 16:24:13

+0

好吧,祝你好運吧!我相信你會學到很多東西。 – Perception 2012-02-24 17:09:02

回答

3

您正在遍歷掃描代碼中的字段,但您定義的註釋僅允許對方法進行註釋。這意味着你永遠不會看到任何註釋。

它看起來像你試圖使用像他們是java bean屬性的字段。下面是使用你的AutoInject和TestClass0類作爲-是setter注入的一個例子:

Main.java:

import java.beans.BeanInfo; 
import java.beans.Introspector; 
import java.beans.PropertyDescriptor; 
import java.lang.annotation.Annotation; 
import java.lang.reflect.Method; 

public class Main { 
    public TestClass0 ts0; 

    public TestClass0 getTso() { 
     return ts0; 
    } 

    @AutoInject 
    public void setTso(TestClass0 ts) { 
     ts0 = ts; 
    } 

    public static void main(String[] args) { 
     // Create instance 
     Main main = new Main(); 
     injectDependencies(main).getTso().printSomething(); 

    } 

    public static <T> T injectDependencies(final T obj) { 
     try { 
      Class clazz = obj.getClass(); 
      BeanInfo beanInfo = Introspector.getBeanInfo(clazz); 

      for (PropertyDescriptor pd : beanInfo.getPropertyDescriptors()) { 
       Method readMethod = pd.getReadMethod(); 
       Method writeMethod = pd.getWriteMethod(); 

       if (writeMethod == null) { 
        continue; 
       } 

       Object existingVal = pd.getReadMethod().invoke(obj); 
       if (existingVal == null) { 
        for (Annotation annotation : writeMethod.getAnnotations()) { 
         if (annotation instanceof AutoInject) { 
          Class propertyType = pd.getPropertyType(); 
          writeMethod.invoke(obj, propertyType.newInstance()); 
         } 
        } 
       } 
      } 
     } catch (Exception e) { 
      // do something intelligent :) 
     } 
     return obj; 
    } 

} 
+0

嗨,看起來不錯,但你傳遞主要的實際對象。如果你創建一個新的主對象,你將不得不回憶這種方法,對吧?例如,如果你看看Spring的注入,當你做新的Main()時,你會有一些依賴,自動注入(通常是一個單例對象)。這個想法是你一次掃描所有的類文件(在啓動時),並使每個新的對象都有一些添加的行爲。 – momomo 2012-02-27 08:22:45

+0

Spring使用中心上下文創建/傳遞所有對象(ApplicationContext)。我的代碼沒有,因爲我試圖說明註釋相關的代碼是如何工作的。關於與這個主類關聯的注入代碼沒有任何內容,您可以輕鬆地將它放入自己的自制注入器類中,該類可以讀入配置並獲取對象創建/服務位置的請求。 – gorjusborg 2012-02-27 14:59:45