InstantiationAwareBeanPostProcessor和@Autowired,@Value的依赖注入

在上篇博文中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和@Autowired,@Value的依赖注入_第1张图片

 实现了InstantiationAwareBeanPostProcessor接口的bean,是@Autowired和@Value的依赖注入的关键。

InstantiationAwareBeanPostProcessor和@Autowired,@Value的依赖注入_第2张图片

同样是这个类,但是调用的方法是postProcessPropertyValues,我们点进这个方法。

InstantiationAwareBeanPostProcessor和@Autowired,@Value的依赖注入_第3张图片

 首先根据beanName找到这个bean对应的InjectionMetadata对象,这个对象中封装了需要依赖注入的属性或者方法。然后调用inject方法。点进去。

InstantiationAwareBeanPostProcessor和@Autowired,@Value的依赖注入_第4张图片

 这里循环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);

点进去看:

InstantiationAwareBeanPostProcessor和@Autowired,@Value的依赖注入_第5张图片

 点进这个代码中,我们来看看关键代码:

InstantiationAwareBeanPostProcessor和@Autowired,@Value的依赖注入_第6张图片

InstantiationAwareBeanPostProcessor和@Autowired,@Value的依赖注入_第7张图片

InstantiationAwareBeanPostProcessor和@Autowired,@Value的依赖注入_第8张图片

String[] result = lbf.getBeanNamesForType(type, includeNonSingletons, allowEagerInit);

我们都知道这个代码是根本类型type找到这个type对应的所有bean的名称,

 然后在这里根据bean的名称获取到bean的实例,然后建立映射关系。entry.getValue()是从对应的map中拿到了这个类型对应的实例。这样@Autowired对应的类型对应的实例从BeanFactory找到了。接下来就需要设置到Field中了。

InstantiationAwareBeanPostProcessor和@Autowired,@Value的依赖注入_第9张图片

在这里一个简单的反射,根据bean和value把对应的value值设置到了对应的bean中。这样基于@Autowired的依赖注入就完成了。这个是Field的依赖注入。而方法的依赖注入基本上跟Field的差不多,只是方法的是method.invoke()调用而已,获取值的过程是一模一样的。

这个就是@Autowired和@Value依赖注入过程,谢谢大家!!

 

 

你可能感兴趣的:(spring源码)