《spring設計思想》9-IntrantiationAwareBeanPostProcessor::實例化前回調-postProcessBeforeInstantiation

上一節說完BeanDefinition中的beanClass屬性從String轉換成了Class。這一節繼續看看beanDefinition發生了什麼,

回到上一節的方法createBean:

	/**
	 * Central method of this class: creates a bean instance,
	 * populates the bean instance, applies post-processors, etc.
	 * @see #doCreateBean
	 */
	@Override
	protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {

		
		RootBeanDefinition mbdToUse = mbd;

		// Make sure bean class is actually resolved at this point, and
		// clone the bean definition in case of a dynamically resolved Class
		// which cannot be stored in the shared merged bean definition.
		Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
			mbdToUse = new RootBeanDefinition(mbd);
			mbdToUse.setBeanClass(resolvedClass);
		}

		// Prepare method overrides.
		try {
			mbdToUse.prepareMethodOverrides();
		}

		try {
			// 曾經有一份真摯的愛情擺在我面前,我沒有珍惜。。。Give BeanPostProcessors a 
            //chance to return a proxy instead of the target bean instance.
			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
			if (bean != null) {
				return bean;
			}
		}

		try {
			Object beanInstance = doCreateBean(beanName, mbdToUse, args);
			
			return beanInstance;
		}
		}
	}

resolveBeanClass之後,有一段代碼是給編程人員一個機會,打斷正常的bean的實例化過程,自定義實例化操作。所以名字叫bean創建的過程的仙履奇緣,需要實現InstantiaitionAwareBeanPostProcess接口,

仔細觀察一下InstantiationAwareBeanPostProcessor

InstantiationAwareBeanPostProcessor 繼承了 BeanPostProcessor 接口,接口說明上簡單的介紹了一下,這個接口是一個回調接口,定義了在bean的實例化之前和之後被調用的兩個方法,而且是在注入bean的屬性之前。

所以這一點很重要,postProcessBeforeInitialization是在注入配置屬性(properties inject)之前做用到的。看簡單的示例

public class BeanInstranitionAwareImpl 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;
        }
        return null;
    }
}

可以上面的實現,在beanClass是SuperUser的類型時,直接返回一個全新的對象。如果不想特殊處理bean,可以默認返回null,表示該bean還是默認使用spring的實例化方法。

下面是仙履奇緣中至尊寶的英文版本:

* Subinterface of {@link BeanPostProcessor} that adds a before-instantiation callback,
* and a callback after instantiation but before explicit properties are set or
* autowiring occurs.
*
* <p>Typically used to suppress default instantiation for specific target beans,
* for example to create proxies with special TargetSources (pooling targets,
* lazily initializing targets, etc), or to implement additional injection strategies
* such as field injection.
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章