Spring源码分析@Autowired、@Resource注解的区别

       关于Spring中@Autowired、@Resource和@Inject注解的区别请看:@Autowired、@Resource和@Inject注解的区别(最详细),本片文章将会带领你进行源码分析@Autowired、@Resource注解的不同。

       在上面所说的那篇博客中,我们知道:

          Spring对于@Autowired、@Resource注解使用不同的后置处理器进行处理

          @Autowired、@Resource之间的处理方式不同,@Autowired是根据类型,@Resource是根据名称

       在进行源码分析之前,你需要了解以下Bean的生命周期:Spring中bean的生命周期(最详细)其中在第五次调用bean的后置处理器时,完成属性的依赖注入,第五次调用bean的后置处理器的步骤:拿到Spring容器中所有的实现了BeanPostProcessor接口的类,然后判断其是否为InstantiationAwareBeanPostProcessor接口的实现类,如果是调用postProcessProperties方法,完成属性赋值。

       在@Autowired、@Resource和@Inject注解的区别(最详细)文章中,已经知道了Spring使用AutowiredAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor类分别处理@Autowired注解和@Resource注解,他们都实现了InstantiationAwareBeanPostProcessor类,所以标注了@Autowired、@Resource会在第六次调用bean的后置处理器的时候完成属性注入。

                                

 

     从上面两张类的关系图可以看到其都间接实现了InstantiationAwareBeanPostProcessor类,下面我们就一起分析一下源码:

代码块1.AbstractAutowireCapableBeanFactory#populateBean方法

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
	// 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;

	//1.第五次后置处理器,对应着我之前博客里面写的bean生命周期,首先判断这个bean是否是合成的,这个绝大多数是不是合成的,然后判断是否有InstantiationAwareBeanPostProcessors的接口
	if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
		  //2.拿到所有的BeanPostProcessors处置处理器
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
				//3.逐一判断这个后置处理器是否是InstantiationAwareBeanPostProcessor类型的,因为BeanPostProcessor接口是为了统一进行管理bean后置处理器的
				//BeanPostProcessor还有子接口,用于实现不同的作用,可以参考bean后置处理器那篇博客
			if (bp instanceof InstantiationAwareBeanPostProcessor) {
				InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
				if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
					continueWithPropertyPopulation = false;
					break;
				}
			}
		}
	}
		//4.如果为true,则说明在第五次调用后置处理的时候返回为false,这样就不会进行属性注入了
		//所以当你想bean中不进行属性注入,可以实现InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation方法
	if (!continueWithPropertyPopulation) {
		return;
	}

	PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

	// 5.解析自动装配模式为AUTOWIRE_BY_NAME和AUTOWIRE_BY_TYPE(现在几乎不用,现在默认是AUTOWIRE_NO)
	/**
	 * <bean id="fruit" class="com.joonwhee.open.demo.simple.Fruit" autowire="byName">
	 *     <property name="color" value="Red"/>
	 * </bean>
	 * id值跟Fruit里的属性名一致
	 * <bean id="apple" class="com.joonwhee.open.demo.simple.Apple"/>
	 *	public class Fruit {
	 * 		private Apple apple;//apple 会根据名称完成自动注入
	 * 	    private String color;
	 * }
	 * */
	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;
	}
		//6.检查是否有InstantiationAwareBeanPostProcessors接口的类
	boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
	boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

	if (hasInstAwareBpps || needsDepCheck) {
		if (pvs == null) {
			pvs = mbd.getPropertyValues();
		}
		PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
		if (hasInstAwareBpps) {
			//7.执行第六次后置处理器,完成属性赋值
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
					//在Spring5.1之后,使用的是postProcessProperties方法完成属性注入
					PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
					if (pvsToUse == null) {
						if (filteredPds == null) {
							filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
						}
						pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
						if (pvsToUse == null) {
							return;
						}
					}
					pvs = pvsToUse;
				}
			}
		}
		//8.依赖检查,对应depends-on属性
		if (needsDepCheck) {
			checkDependencies(beanName, mbd, filteredPds, pvs);
		}
	}
	//9.将所有PropertyValues中的属性填充到bean中
	if (pvs != null) {
		applyPropertyValues(beanName, mbd, bw, pvs);
	}
}

       AbstractAutowireCapableBeanFactory#populateBean方法是在Spring启动时,完成非懒加载单实例bean注册到容器时会执行的方法,可以对着Spring中bean的生命周期(最详细)来进行分析,populateBean方法会执行bean生命周期的第五、第六次后置处理器,第五次就不做分析了,关键进行分析第六次完成属性注入的生命周期,在populateBean方法中的第7步,会拿到所有的BeanPostProcessors方法,然后判断是否是InstantiationAwareBeanPostProcessor类型的,如果是则执行postProcessPropertyValues方法完成属性注入,因为AutowiredAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor类都实现了InstantiationAwareBeanPostProcessor接口,所以会在第7步进行调用各自的方法,我们先看一

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值