注入另一个对象的Java自定义注释

时间:2012-02-24 15:46:29

标签: java annotations

我正在尝试学习如何用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)
                 }

             }

        }
    }

}

正如你在static void main()中看到的那样......我试图在TestClass0中调用该方法,期望它可用。我知道上面的内容很快就会完成,但我刚开始学习注释并希望得到你的指导。

我们如何触发一段代码,在上或在调用 get方法时初始化属性。使用注释。我在想而不改变调用方法。

谢谢!

1 个答案:

答案 0 :(得分: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;
    }

}