Spring5 源码阅读笔记(1.4.2.4)populateBean(beanName, mbd, instanceWrapper) 填充Bean

回顾
1.4.2 createBean(beanName, mbd, args)
我们讲获取 Bean 实例的过程

1.4.2.1 createBeanInstance(beanName, mbd, args)
通过构造函数创建 Bean 实例。
构造函数上如果有 @Autowired,会先将引用类型的入参对象优先实例化。
但此时的 Bean 实例里的属性上、非构造方法上如果有 @Autowired,还没有进行依赖注入。

1.4.2.2 applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName)
请求 CommonAnnotationBeanPostProcessor 和 AutowiredAnnotationBeanPostProcessor,
扫描方法上是否有@PostConstruct @PreDestroy注解,有注解的封装成 LifecycleMetadata
扫描方法和属性上是否有@Resource注解
扫描方法和属性上是否有@Autowired @Value注解
对这些有注解的方法和属性封装成 InjectionMetadata

本节重点
本节的方法 populateBean 实现了对有 @Autowired 和 @Resource 的属性和非构造方法进行依赖注入。

无论是 CommonAnnotationBeanPostProcessor 还是 AutowiredAnnotationBeanPostProcessor,类的内部都有一个 map 来存储 InjectionMetadata

private final transient Map<String, InjectionMetadata> injectionMetadataCache = new ConcurrentHashMap<>(256);

populateBean 这个方法正是从这个缓存里拿到的 InjectionMetadata,进而通过 InjectionMetadata 里的信息来进行依赖注入。当然,注入的实例会进行优先实例化。

跟源码
类 AbstractAutowireCapableBeanFactory

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
	if (bw == null) {
		if (mbd.hasPropertyValues()) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
		}
		else {
			// Skip property population phase for null instance.
			return;
		}
	}

	// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
	// state of the bean before properties are set. This can be used, for example,
	// to support styles of field injection.
	boolean continueWithPropertyPopulation = true;

	//这里很有意思,写接口可以让所有类都不能依赖注入
	if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			if (bp instanceof InstantiationAwareBeanPostProcessor) {
				InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
				if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {

					//是否需要DI,依赖注入
					continueWithPropertyPopulation = false;
					break;
				}
			}
		}
	}

	if (!continueWithPropertyPopulation) {
		return;
	}

	//不看
	PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
	if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
		MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
		// Add property values based on autowire by name if applicable.
		if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) {
			autowireByName(beanName, mbd, bw, newPvs);
		}
		// Add property values based on autowire by type if applicable.
		if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
			autowireByType(beanName, mbd, bw, newPvs);
		}
		pvs = newPvs;
	}

	boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
	boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

	PropertyDescriptor[] filteredPds = null;

	//重要程度:5
	if (hasInstAwareBpps) {
		if (pvs == null) {
			pvs = mbd.getPropertyValues();
		}
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			if (bp instanceof InstantiationAwareBeanPostProcessor) {
				InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
				//依赖注入过程,@Autowired @Resource 的支持
				PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
				if (pvsToUse == null) {
					if (filteredPds == null) {
						filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
					}

					//老版本用这个完成依赖注入过程,@Autowired的支持
					pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
					if (pvsToUse == null) {
						return;
					}
				}
				pvs = pvsToUse;
			}
		}
	}
	if (needsDepCheck) {
		if (filteredPds == null) {
			filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
		}
		checkDependencies(beanName, mbd, filteredPds, pvs);
	}

	//重要程度:0 老版本用<property name="username" value="Jack"/>
	//标签做依赖注入的代码实现,复杂且无用
	if (pvs != null) {
		applyPropertyValues(beanName, mbd, bw, pvs);
	}
}

跟 postProcessProperties:
类 InstantiationAwareBeanPostProcessor
在这里插入图片描述
这两种差不多,我们先看 CommonAnnotationBeanPostProcessor:

@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
	//这个方法 1.4.2.2 已经看过了,先从缓存里找,没有就去创建
	InjectionMetadata metadata = findResourceMetadata(beanName, bean.getClass(), pvs);
	try {
		metadata.inject(bean, beanName, pvs);
	}
	catch (Throwable ex) {
		throw new BeanCreationException(beanName, "Injection of resource dependencies failed", ex);
	}
	return pvs;
}

跟 inject:
类 InjectionMetadata.InjectedElement

public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
	Collection<InjectedElement> checkedElements = this.checkedElements;
	Collection<InjectedElement> elementsToIterate =
			(checkedElements != null ? checkedElements : this.injectedElements);
	if (!elementsToIterate.isEmpty()) {
		for (InjectedElement element : elementsToIterate) {
			if (logger.isTraceEnabled()) {
				logger.trace("Processing injected element of bean '" + beanName + "': " + element);
			}
			if(element.isField) {
				Field field = (Field)element.member;
			}
			element.inject(target, beanName, pvs);
		}
	}
}

跟 inject:

protected void inject(Object target, @Nullable String requestingBeanName, @Nullable PropertyValues pvs)
				throws Throwable {
	
	if (this.isField) {
		Field field = (Field) this.member;
		ReflectionUtils.makeAccessible(field);
						  //这里面有 getBean 操作
		field.set(target, getResourceToInject(target, requestingBeanName));
	}
	else {
		if (checkPropertySkipping(pvs)) {
			return;
		}
		try {
			Method method = (Method) this.member;
			ReflectionUtils.makeAccessible(method);
			method.invoke(target, getResourceToInject(target, requestingBeanName));
		}
		catch (InvocationTargetException ex) {
			throw ex.getTargetException();
		}
	}
}

对于 AutowiredAnnotationBeanPostProcessor 也是调用 metadata.inject(bean, beanName, pvs),但 AutowiredAnnotationBeanPostProcessor 里面有2个私有类重写了这个方法:
在这里插入图片描述

我们只看 AutowiredFieldElement 的:

@Override
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
	Field field = (Field) this.member;
	Object value;
	if (this.cached) {
		value = resolvedCachedArgument(beanName, this.cachedFieldValue);
	}
	else {
		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 {
			//这里面有getBean的操作,拿到依赖的实例
			value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
		}
		catch (BeansException ex) {
			throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
		}
		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) &&
								beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
							this.cachedFieldValue = new ShortcutDependencyDescriptor(
									desc, autowiredBeanName, field.getType());
						}
					}
				}
				else {
					this.cachedFieldValue = null;
				}
				this.cached = true;
			}
		}
	}

	if (value != null) {
		ReflectionUtils.makeAccessible(field);
		//依赖注入
		field.set(bean, value);
	}
}
发布了130 篇原创文章 · 获赞 233 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_44367006/article/details/104425189