spring bean生命周期三---Spring Bean populateBean 属性填充阶段

本文详细探讨了Spring Bean的populateBean阶段,包括属性填充判断、autowiring自动装配、@Autowired和@Resource的注入工作。重点解析了autowireByName、autowireByType、InstantiationAwareBeanPostProcessor的postProcessProperties方法,以及AutowiredAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor的角色。文章旨在帮助读者深入理解Spring Bean的属性注入过程。
摘要由CSDN通过智能技术生成

目录

 

前言

一、populateBean - 概述

二、populateBean - 详解

2.1. 属性填充判断 

2.2、自动装配 :autowiring自动装配的

2.2.1、自动装配 - autowireByName

2.2.2、 自动装配 - autowireByType

2.3、排除规则 - unsatisfiedNonSimpleProperties

3、@Autowired 和 @Resource 的注入工作

3.1、第六次调用后置处理器  InstantiationAwareBeanPostProcessor#postProcessProperties

3.2、CommonAnnotationBeanPostProcessor#postProcessPropertyValues

3.3、AutowiredAnnotationBeanPostProcessor #postProcessPropertyValues

3.4、需要依赖注入的对象 DefaultListableBeanFactory#resolveDependency 

4. applyPropertyValues

三、总结


前言

本文是笔者阅读Spring源码的记录文章,由于本人技术水平有限,在文章中难免出现错误,如有发现,感谢各位指正。

我们在上一篇文章:spring bean生命周期二---Spring Bean实例化( Instantiation)阶段 中完成了bean的实例化过程 ,但是属性内容还没有注入,本文就是将bean的属性进行注入的过程

一、populateBean - 概述

我们这里先整体过一遍代码,后面进行每一步的详细解读。

// AbstractAutowireCapableBeanFactory#populateBean
	// beanName : bean 的name
	// mbd  :  bean的定义信息
	// bw  : bean实例的包装类型,里面有bean的实例
	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;
         //mbd.isSynthetic() 合成类
		//todo 第五次---判断属性是否填充:InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation
		// 给InstantiationAwareBeanPostProcessor最后一次机会在属性设置前来改变bean
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
					if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
						continueWithPropertyPopulation = false;
						break;
					}
				}
			}
		}

		if (!continueWithPropertyPopulation) {
			return;
		}
		//获取容器在解析Bean定义资源时为BeanDefiniton中设置的属性值
		//这个是程序员在 bd中 写入的属性rootBeanDefinition.getPropertyValues().add("type","男的");
		PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

		 2. 自动装配 :autowiring自动装配的。根据名称或类型自动注入
		if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
				mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {


			MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

			// Add property values based on autowire by name if applicable.
			//根据Bean名称进行autowiring自动装配处理
			if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
				autowireByName(beanName, mbd, bw, newPvs);
			}

			// Add property values based on autowire by type if applicable.
			//根据Bean类型进行autowiring自动装配处理
			if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
				autowireByType(beanName, mbd, bw, newPvs);
			}

			pvs = newPvs;
		}
		//对非autowiring的属性进行依赖注入处理
		// 后处理器已经初始化
		boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
		boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);

		if (hasInstAwareBpps || needsDepCheck) {
			if (pvs == null) {
				pvs = mbd.getPropertyValues();
			}
			PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
			if (hasInstAwareBpps) {
				//TODO 获取的bean所有后置处理器找到 所有需要注入的属性
				// 这里会进行 @Autowired 和 @Resource 的注入工作
				// 属性填充InstantiationAwareBeanPostProcessor
				for (BeanPostProcessor bp : getBeanPostProcessors()) {
					if (bp instanceof InstantiationAwareBeanPostProcessor) {
						InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
						//下面是完成属性注入的
						pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
						// 如果postProcessProperties 返回null,再调用 postProcessPropertyValues这个过时的方法
						if (pvs == null) {
							return;
						}
					}
				}
			}
			if (needsDepCheck) {
				// 依赖检查,对应 depends-on 属性,3.0 已弃用
				checkDependencies(beanName, mbd, filteredPds, pvs);
			}
		}
		if (pvs != null) {
			 4. 将属性应用到bean中
			applyPropertyValues(beanName, mbd, bw, pvs);
		}
	}

从上看下来,整个流程如下:

  1. InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation 方法,可以决定程序是否继续进行属性填充。只要有一个 InstantiationAwareBeanPostProcessor 返回false,都会终止属性填充的过程。这个过程属于实例化 后置阶段上上文已经描述过了
  2. 自动装配 :autowiring自动装配的。根据注入类型(name或type),提取依赖的bean,并统一存入到 propertyValues 中。
  3. @Autowired 和 @Resource 的属性注入工作,调用后置处理器应用 InstantiationAwareBeanPostProcessor#postProcessProperties 方法,对属性获取完毕填充前对属性的再次处理。

         有两个实现类型 :1、AutowiredAnnotationBeanPostProcessor 中的实现类 处理 @Autowired 注解的

                                        2、AutowiredAnnotationBeanPostProcessor 中的实现类 处理 @Autowired 注解的

  1. 将所有 propertyValues 中的属性填充至 BeanWrapper 中。

在这里方法里按照如下顺序调用了后处理器

  • InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation : 是否使用 InstantiationAwareBeanPostProcessor进行属性装配
  • InstantiationAwareBeanPostProcessor.postProcessProperties : 进行属性装配

二、populateBean - 详解

2.1. 属性填充判断 

这个的上文中已经描述过了这里就简单贴出代码

 //mbd.isSynthetic() 合成类
		//todo 第五次---判断属性是否填充:InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation
		// 给InstantiationAwareBeanPostProcessor最后一次机会在属性设置前来改变bean
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
					if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
						continueWithPropertyPopulation = false;
						break;
					}
				}
			}
		}

如下,这里调用了InstantiationAwareBeanPostProcessor #postProcessAfterInstantiation 方法来决定是否继续注入属性。该方法正常返回true。如果返回false 则将取消对此bean调用任何后续的InstantiationAwareBeanPostProcessor 方法。

2.2、自动装配 :autowiring自动装配的

在下面这段代码中,对 autowiring自动装配中根据名称或类型自动注入的种类进行自动装配。


    		 2. 自动装配 :autowiring自动装配的。根据名称或类型自动注入
		if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
				mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {


			MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

			// Add property values based on autowire by name if applicable.
			//根据Bean名称进行autowiring自动装配处理
			if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
				autowireByName(beanName, mbd, bw, newPvs);
			}

			// Add property values based on autowire by type if applicable.
			//根据Bean类型进行autowiring自动装配处理
			if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
				autowireByType(beanName, mbd, bw, newPvs);
			}

			pvs = newPvs;
		}

这一段代码的目的是,如果bean在声明的时候指定了自动注入类型是 byName或者byType,则会根据这个规则,对 bean内部的排除某些特定的属性(排除规则后面详解), 进行byName 或者 byType的自动装配。

2.2.1、自动装配 - autowireByName

//根据名称对属性进行自动依赖注入
	protected void autowireByName(
			String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {

		//对Bean对象中非简单属性(不是简单继承的对象,如8中原始类型,字符串,URL等都是简单属性)进行处理
		String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
		for (String propertyName : propertyNames) {
			//如果Spring IOC容器中包含指定名称的Bean
			if (containsBean(propertyName)) {
				//调用getBean方法向IOC容器索取指定名称的Bean实例,迭代触发属性的初始化和依赖注入
				Object bean = getBean(propertyName);
				//为指定名称的属性赋予属性值
				pvs.add(propertyName, bean);
				//指定名称属性注册依赖Bean名称,进行属性依赖注入
				registerDependentBean(propertyName, beanName);
				if (logger.isDebugEnabled()) {
					logger.debug("Added autowiring by name from bean name '" + beanName +
							"' via property '" + propertyName + "' to bean named '" + propertyName + "'");
				}
			}
			else {
				if (logger.isTraceEnabled()) {
					logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
							"' by name: no matching bean found");
				}
			}
		}
	}

可以看到,byName 的处理逻辑很简单,一句话概括,获取需要注入的bean然后递归调用getBean获取bean进行注入。 关于 unsatisfiedNonSimpleProperties

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值