《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在實例化之後,初始化之前調用。

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