spring(十八)----populateBean(第五、六次调用后置处理器)

话不多说,先看代码:

	/**
	 * Populate the bean instance in the given BeanWrapper with the property values
	 * from the bean definition.
	 * @param beanName the name of the bean
	 * @param mbd the bean definition for the bean
	 * @param bw the BeanWrapper with bean instance
	 */
	@SuppressWarnings("deprecation")  // for postProcessPropertyValues
	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.
		//判断是否需要属性设置
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {//第五次
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
					if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
						return;
					}
				}
			}
		}

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

		int resolvedAutowireMode = mbd.getResolvedAutowireMode();
		if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
			MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
			// Add property values based on autowire by name if applicable.
			if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
				autowireByName(beanName, mbd, bw, newPvs);
			}
			// Add property values based on autowire by type if applicable.
			if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
				autowireByType(beanName, mbd, bw, newPvs);
			}
			pvs = newPvs;
		}

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

		PropertyDescriptor[] filteredPds = null;
		if (hasInstAwareBpps) {
			if (pvs == null) {
				pvs = mbd.getPropertyValues();
			}
			for (BeanPostProcessor bp : getBeanPostProcessors()) {//第六次
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
					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;
				}
			}
		}
		if (needsDepCheck) {
			if (filteredPds == null) {
				filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
			}
			checkDependencies(beanName, mbd, filteredPds, pvs);
		}

		if (pvs != null) {
			applyPropertyValues(beanName, mbd, bw, pvs);
		}
	}

其中第五次和第六次调用后置处理器的关键代码:

		//判断是否需要属性设置
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {//第五次
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
					if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
						return;
					}
				}
			}
		}
			for (BeanPostProcessor bp : getBeanPostProcessors()) {//第六次
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
					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;
				}
			}

为什么这2个要一起说呢,因为这两个是一起作用的。
1、当第五次调用的时候。如果判断返回了false,那么第六次就不再执行了。
2、当第五次调用的时候。如果判断返回了true,那么第六次将继续执行。
3、从第六次执行代码可以看出:如果我们返回为null,spring将会自行再处理一次。这样就避免了返回为null的情况。

我们接着前面的代码来。
修改一下test和app的代码:

package test.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import test.dao.Dao;

@Component
public class Test {
	@Autowired
	Dao dao;

	public void test(){
		System.out.println(dao);
	}
}

package test;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import test.config.Appconfig;
import test.config.Test;
import test.dao.Dao;
import test.dao.DaoImpl;
import test.service.DaoService;
import test.service.MYService;

import java.io.IOException;

public class App {
	public static void main(String[] args) {
		AnnotationConfigApplicationContext annotationConfigApplicationContext=new AnnotationConfigApplicationContext();
		annotationConfigApplicationContext.register(Appconfig.class);
		annotationConfigApplicationContext.refresh();
//		System.out.println((Dao)(annotationConfigApplicationContext.getBean("daoImpl")));
		((Test)annotationConfigApplicationContext.getBean("test")).test();

	}
}

我们先看一下不写后置处理器的结果:
在这里插入图片描述

接下来写上后置处理器:

package test.mypostprocessors;

import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.stereotype.Component;

@Component
public class MYInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
	/**
	 * spring第一次调用后置处理器的方法
	 * 这个方法是在实例化之前产生作用,当这个方法不返回null的时候,就会直接调用BeanPostProcessor的postProcessAfterInitialization方法然后直接返回出去
	 * 这样就跳过了中间的许多步骤(如推断构造方法,自动装配)
	 * 如果这个方法返回null,则会按照spring的流程继续走下去
	 * @param beanClass the class of the bean to be instantiated
	 * @param beanName the name of the bean
	 * @return
	 * @throws BeansException
	 */
//	@Override
//	public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
//		if(beanName.equals("daoService"))
//			System.out.println("aaaaaaaa");
		return Proxy.newProxyInstance(this.getClass().getClassLoader(),new Class[]{MYService.class},new MYInvocationHandler());
//		return null;
//	}

	/**
	 * 这个方法是在实例化之后产生作用,由于返回的值是bool类型
	 * 判断是否需要对属性的填充或修改(@Autowired要不要管)
	 * @param bean the bean instance created, with properties not having been set yet
	 * @param beanName the name of the bean
	 * @return
	 * @throws BeansException
	 */

	@Override
	public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
		if(beanName.equals("test"))
			System.out.println("postProcessAfterInstantiation----"+beanName);
		return false;
	}
	//设置属性值
	@Override
	public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
		if(beanName.equals("test")) {
			System.out.println("postProcessProperties----" + beanName);
		}
		return null;
	}
}

因为我手动返回了false,那么test中dao能否拿到呢?
在这里插入图片描述
打印了postProcessAfterInstantiation----test证明使用了我们的后置处理器,postProcessProperties没有打印证明没有使用,而我们能看见test的dao属性为null。而我们正常的不应该是这样,证明第五次返回了false的话,就不会执行第六次了。

如果返回true,那么就一定会执行第六次后置处理器,由于不可能不注入,因此,第六次后置处理器若返回的不合理则spring自己依旧还会去处理,这个过程暂时不说,不属于后置处理器的范畴。
在这里插入图片描述图中能看到postProcessProperties----test打印出来了,证明postProcessProperties调用了,由于我返回的null不合理,spring又自己去实现了一次。这里具体的不详述,有兴趣的可以自己看看这部分的源码:

					if (pvsToUse == null) {
						if (filteredPds == null) {
							filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
						}
						pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
						if (pvsToUse == null) {
							return;
						}
					}

至此,第五次、第六次的后置处理器就说完了。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值