《Spring设计思想》11-InstrantiationAwareBeanPostProcessor,实例化之后回调:postProcessAfterInstantiation

第9节书中写道:beanDefinition实例化之前给了至尊宝一个机会,让他带自己离开,不再进行默认的实例化,但是至尊宝啥也没做

所以第10节beanDefinition还是默认进行了实例化,生成了bean。这个时候紫霞穿好了嫁衣,马上就要拜堂了。他的意中人到底能不能来接他?

这一节我们书接上文,继续看看bean被实例化之后有什么操作。

还是AbstractAutowireCapableBeanFactory.createBean(String beanName,RootBeanDefinition mbd,Object[] args)方法

调用AbstractAutowireCapableBeanFactory.doCreateBean(String beanName,RootBeanDefintion mbd,Object[] args)方法

	protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
			throws BeanCreationException {

		// Instantiate the bean.实例化bean
		BeanWrapper instanceWrapper = createBeanInstance(beanName, mbd, args);
	
		final Object bean = instanceWrapper.getWrappedInstance();
		Class<?> beanType = instanceWrapper.getWrappedClass();

        
		// Initialize the bean instance. 初始化bean
		Object exposedObject = bean;
		try {
			populateBean(beanName, mbd, instanceWrapper);
			exposedObject = initializeBean(beanName, exposedObject, mbd);
		}
		catch (Throwable ex) {
			if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
				throw (BeanCreationException) ex;
			}
			else {
				throw new BeanCreationException(
						mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
			}
		}

		return exposedObject;
	}

方法中可以看到bean在实例化之后要执行初始化操作

1:populateBean(beanName,mbd,instanceWrapper);注入bean的配置属性

2:exposedObject = initializeBean(beanName,exposedObject,mbd);初始化bean,调用aware的回调接口,和beanPostProcessor

简单的看下populateBean(beanName,mbd,instanceWrapper);

	/**
	 * 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) {
		

		// 着重强调,我要给至尊宝一次机会,让他阻止当前的婚礼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)) {
						continueWithPropertyPopulation = false;
						break;
					}
				}
			}
		}

		if (!continueWithPropertyPopulation) {
			return;
		}

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

		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 (pvs != null) {
			applyPropertyValues(beanName, mbd, bw, pvs);
		}
	}

看到属性:continueWithPropertyPopulation的时候,我心里流下了感动的泪水,这个地方是紫霞仙子给至尊宝留下的一个机会,让他可以终止当前的婚礼,还是前面讲到的接口InstantiationAwareBeanPostProcessor:

第9节描述的是postProcessorBeforeInstantiation方法,这个地方调用的是posrProcessorAfterInstantiation(Object,String)

看简单的实现

public class BeanInstantiaitionAwareImpl implements InstantiationAwareBeanPostProcessor {

    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
//        Assert.isNull(beanClass,"beanClass不能为空");
        if(ObjectUtils.nullSafeEquals(beanClass, SuperUser.class)){
            SuperUser superUser = new SuperUser();
            superUser.setName("一个船新的版本");
            superUser.setAge(22);
            return superUser;
        }
        //默认什么都不做,返回null,继续下一步实例化
        return null;
    }

    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        if(bean.getClass().equals(User.class)){
            User user = (User) bean;
            user.setName("至尊宝");
            user.setAge(589);
            return false;
        }
        //默认返回true,什么也不做,继续下一步 初始化
        return true;
    }
}

断点调试:

调用堆栈

不再继续populateBean方法,

看输出结果:

至尊宝来了:

到这里我们看到,InstantiationAwareBeanPostProcessor的两个方法

postProcessorBeforeInstantiation在实例化之前调用

postProcessorAfterInstantiation在实例化之后,初始化之前调用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章