了解Autowired注解,是為了了解自定義注解的實現
1.InjectedElement
1.1 AutowiredFieldElement表示被Autowired注解標記的字段
1.2 AutowiredMethodElement表示被Autowired注解標記的方法
表示被注入的元素,其包含2個子類
InjectedElement
代碼實例1:
如下代碼,testBean就表示一個被注入的元素
public class AutowiredTestBean {
@Autowired
private TestBean testBean;
MethodTestBean methodTestBean;
@Autowired
public void setMethodTestBean(MethodTestBean methodTestBean) {
this.methodTestBean = methodTestBean;
}
public String getName() {
return testBean.getName() + "_" + methodTestBean.getName();
}
}
2.InjectionMetadata
注入的元數據,包含一個Class和InjectedElement集合,如AutowiredTestBean,Class就是AutowiredTestBean,InjectedElement集合包含一個AutowiredFieldElement和一個AutowiredMethodElement
public class InjectionMetadata {
private final Class<?> targetClass;
private final Collection<InjectedElement> injectedElements;
public InjectionMetadata(Class<?> targetClass, Collection<InjectedElement> elements) {
this.targetClass = targetClass;
this.injectedElements = elements;
}
}
3.inject
找到要注入的對象,接著就需要對InjectionMetadata中的InjectedElement集合進行對象注入了
在InjectedElement實現了一個inject方法.
AutowiredFieldElement和AutowiredMethodElement各自重寫了InjectedElement的inject方法.
可以猜測一下,內部的實現肯定是涉及到beanFactory的,如下代碼
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Field field = (Field) this.member;
Object value;
DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
desc.setContainingClass(bean.getClass());
Set<String> autowiredBeanNames = new LinkedHashSet<>(1);
Assert.state(beanFactory != null, "No BeanFactory available");
TypeConverter typeConverter = beanFactory.getTypeConverter();
try {
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
}
if (value != null) {
ReflectionUtils.makeAccessible(field);
field.set(bean, value);
}
}
總結一下:
- 自定義一個注解
- 自定義一個BeanPostProcessor(AutowiredAnnotationBeanPostProcessor)檢測注解
- 自定義InjectedElement并實現inject方法,最后返回InjectionMetadata