2012-02-24 90 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