在上篇博文中https://blog.csdn.net/luoyang_java/article/details/85709475我们说了,MergedBeanDefinitionPostProcessor扫描了bean,并且把bean中有@Autowired和@Value注解的field和method封装成了InjectionMetadata对象。这篇博文,我们来说说,spring是怎么根据封装的InjectionMetadata对象来镜像IOC依赖注入的。
首先IOC依赖注入的入口是:
populateBean(beanName, mbd, instanceWrapper);
进入这个方法,其中@Autowired和@Value的依赖注入是在
实现了InstantiationAwareBeanPostProcessor接口的bean,是@Autowired和@Value的依赖注入的关键。
同样是这个类,但是调用的方法是postProcessPropertyValues,我们点进这个方法。
首先根据beanName找到这个bean对应的InjectionMetadata对象,这个对象中封装了需要依赖注入的属性或者方法。然后调用inject方法。点进去。
这里循环InjectionMetadata里面的injectedElements,上篇博文中我们讲过,injectedElements是封装了有注解的Field和Method,并且有PropertyDescriptor 描述对象。就是挨个对每一个Field或者Method进行依赖注入处理。
这里我们对Field依赖注入看看源码:
@Override
protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable {
Field field = (Field) this.member;
try {
Object value;
if (this.cached) {
value = resolvedCachedArgument(beanName, this.cachedFieldValue);
}
else {
DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
desc.setContainingClass(bean.getClass());
Set autowiredBeanNames = new LinkedHashSet(1);
TypeConverter typeConverter = beanFactory.getTypeConverter();
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
synchronized (this) {
if (!this.cached) {
if (value != null || this.required) {
this.cachedFieldValue = desc;
registerDependentBeans(beanName, autowiredBeanNames);
if (autowiredBeanNames.size() == 1) {
String autowiredBeanName = autowiredBeanNames.iterator().next();
if (beanFactory.containsBean(autowiredBeanName)) {
if (beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
this.cachedFieldValue = new RuntimeBeanReference(autowiredBeanName);
}
}
}
}
else {
this.cachedFieldValue = null;
}
this.cached = true;
}
}
}
if (value != null) {
ReflectionUtils.makeAccessible(field);
field.set(bean, value);
}
}
catch (Throwable ex) {
throw new BeanCreationException("Could not autowire field: " + field, ex);
}
}
这个代码是Field的依赖注入过程,其中的关键是@Autowired是要根据Field的类型,把该类型对应的实例从BeanFactory中拿到对应实例。这个代码在:value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
点进去看:
点进这个代码中,我们来看看关键代码:
String[] result = lbf.getBeanNamesForType(type, includeNonSingletons, allowEagerInit);
我们都知道这个代码是根本类型type找到这个type对应的所有bean的名称,
然后在这里根据bean的名称获取到bean的实例,然后建立映射关系。entry.getValue()是从对应的map中拿到了这个类型对应的实例。这样@Autowired对应的类型对应的实例从BeanFactory找到了。接下来就需要设置到Field中了。
在这里一个简单的反射,根据bean和value把对应的value值设置到了对应的bean中。这样基于@Autowired的依赖注入就完成了。这个是Field的依赖注入。而方法的依赖注入基本上跟Field的差不多,只是方法的是method.invoke()调用而已,获取值的过程是一模一样的。
这个就是@Autowired和@Value依赖注入过程,谢谢大家!!