Java實現Autowired自動注入
阿新 • • 發佈:2021-07-17
首發於Enaium的個人部落格
繼續使用上個文章的類容器
建立一個註解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Autowired {
}
遍歷所有欄位包括私有的
private void autowired() { for (Map.Entry<Class<?>, Object> classObjectEntry : classes.entrySet()) { for (Field declaredField : classObjectEntry.getKey().getDeclaredFields()) { declaredField.setAccessible(true); if (classes.get(declaredField.getType()) != null) {//容器內是否有這個類的物件 try { //賦值 declaredField.set(classObjectEntry.getValue(), classes.get(declaredField.getType())); } catch (IllegalAccessException e) { e.printStackTrace(); } } } } }
在加入到容器後就呼叫autowired
public ClassContainer() { List<Class<?>> scanClasses = new ArrayList<>(List.of(Test1.class, Test2.class));//注意這裡Test2也被加入到了容器裡 scanClasses.forEach(it -> { try { classes.put(it, it.getConstructor().newInstance()); } catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) { e.printStackTrace(); } }); autowired(); }
public <T> T create(Class<T> klass, Object instance) {
classes.put(klass, instance);
autowired();
return (T) classes.get(klass);
}
建立Test3
public class Test3 {
public void render() {
System.out.println("Test3");
}
}
Test1使用Autowired
public class Test1 { @Autowired private Test2 test2; @Autowired private Test3 test3; public void render() { test2.render(); test3.render(); } }
測試一下
public class Main {
private static final ClassContainer classContainer = new ClassContainer();
public static void main(String[] args) {
classContainer.create(Test1.class).render();
}
}
Test2正常 Test3空指標 因為不在容器裡