我正在尝试学习如何用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方法时初始化属性。使用注释。我在想而不改变调用方法。
谢谢!
答案 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;
}
}