天天看點

【源碼】Spring —— BeanFactory 解讀 3 AbstractAutowireCapableBeanFactory前言版本AbstractAutowireCapableBeanFactory總結

【源碼】Spring —— BeanFactory 解讀 3 AbstractAutowireCapableBeanFactory

  • 前言
  • 版本
  • AbstractAutowireCapableBeanFactory
    • createBean
    • doCreateBean
    • getEarlyBeanReference
    • populateBean
    • initializeBean
    • 其他方法
  • 總結

前言

上一章節解讀了頂層抽象實作類

AbstractBeanFactory

,它主要實作了

BeanFactory

HierarchicalBeanFactory

ConfigurableBeanFactory

定義的大多數方法

其中,

BeanFactory#getBean

方法的實作最終是委托在抽象方法

createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] arg

的,

AbstractAutowireCapableBeanFactory

便提供了該方法的實作,本文會重點解讀該方法

版本

Spring 5.3.x

AbstractAutowireCapableBeanFactory

public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
		implements AutowireCapableBeanFactory
           

AbstractAutowireCapableBeanFactory

AbstractBeanFactory

的子類,同時實作了

AutowireCapableBeanFactory

,之前提到

AutowireCapableBeanFactory

接口拓展了

自動裝配

的能力,

AbstractAutowireCapableBeanFactory

便提供了相關實作

createBean

上文提到,

AbstractBeanFactory

實作

getBean

方法的邏輯最終是委托在抽象方法

createBean

的,

AbstractAutowireCapableBeanFactory

給出了該方法的實作

// 核心方法,建立bean執行個體、屬性填充、後置處理等
	@Override
	protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {

		RootBeanDefinition mbdToUse = mbd;

		// 解析類型(AbstractBeanFactory#resolveBeanClass)
		Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
			mbdToUse = new RootBeanDefinition(mbd);
			mbdToUse.setBeanClass(resolvedClass);
		}

		try {
			mbdToUse.prepareMethodOverrides();
		}
		catch (BeanDefinitionValidationException ex) {
			// ...
		}

		try {
			// 這個地方,允許 後置處理器 提前傳回一個代理執行個體
			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
			if (bean != null) {
				return bean;
			}
		}
		catch (Throwable ex) {
			// ...
		}

		try {
			// 建立bean
			Object beanInstance = doCreateBean(beanName, mbdToUse, args);
			return beanInstance;
		}
		catch (Throwable ex) {
			// ...
		}
	}

	@Nullable
	protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
		Object bean = null;
		if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
			if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
				Class<?> targetType = determineTargetType(beanName, mbd);
				if (targetType != null) {

					/**
					 * 如果 InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation
					 * 		傳回一個非空執行個體,則 生命周期 短路,直接執行所有後置處理器的
					 * 		postProcessAfterInitialization 方法
					 */
					bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
					if (bean != null) {
						bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
					}
				}
			}
			mbd.beforeInstantiationResolved = (bean != null);
		}
		return bean;
	}
           

代碼如上,略去了列印日志等,做個概括:

  • 在建立

    bean執行個體

    前,有個重要方法

    resolveBeforeInstantiation

    :此處會執行

    InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation

    ,如果傳回非

    null

    ,則短路生命周期傳回目标執行個體
  • 如果上述方法傳回

    null

    (大多數場景),則由

    doCreateBean

    方法建立

    bean執行個體

doCreateBean

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

		BeanWrapper instanceWrapper = null;

		// 如果是單例,從 工廠bean 緩存擷取并清除緩存
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}

		// 如果為空,則建立對應的 BeanWrapper
		if (instanceWrapper == null) {
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}

		// 取出包裝的執行個體進行後續處理
		Object bean = instanceWrapper.getWrappedInstance();
		Class<?> beanType = instanceWrapper.getWrappedClass();
		if (beanType != NullBean.class) {
			mbd.resolvedTargetType = beanType;
		}
		
		// 執行所有的 MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition
		synchronized (mbd.postProcessingLock) {
			if (!mbd.postProcessed) {
				try {
					applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
				}
				catch (Throwable ex) {
					// ...
				}
				mbd.postProcessed = true;
			}
		}

		/**
		 * 如果允許 循環依賴,此處會建立對應的 單例工廠
		 *  	并将其緩存到 二級單例緩存(singletonFactories) 中
		 *  	getObject 方法委托給 getEarlyBeanReference 方法
		 */
		boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
				isSingletonCurrentlyInCreation(beanName));
		if (earlySingletonExposure) {
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
		}

		Object exposedObject = bean;
		try {
			// 屬性填充
			populateBean(beanName, mbd, instanceWrapper);

			// 初始化操作:工廠回調、初始化回調、後處理
			exposedObject = initializeBean(beanName, exposedObject, mbd);
		}
		catch (Throwable ex) {
			// ...
		}

		/**
		 * 對于循環依賴的 bean,此處嘗試從三級緩存擷取
		 */
		if (earlySingletonExposure) {
			Object earlySingletonReference = getSingleton(beanName, false);
			if (earlySingletonReference != null) {
				if (exposedObject == bean) {
					exposedObject = earlySingletonReference;
				}
				// ...
			}
		}

		// ...

		return exposedObject;
	}
           
  • createBeanInstance

    方法用于建立

    bean

    執行個體對象,該過程是我認為建立

    bean

    過程中最最複雜的方法了 ,包括構造器的推斷等諸多細節,此處不展開讨論
  • 執行所有的

    MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition

    @Autowired

    @Value

    注解處理相關在此處有涉及
  • 對于需要處理

    循環依賴

    的執行個體,此處會借助

    工廠緩存

    進行處理
  • 核心方法

    populateBean

    :填充

    bean執行個體

    的屬性
  • initializeBean

    方法進行

    bean執行個體

    的後續處理:初始化回調等

getEarlyBeanReference

protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
		Object exposedObject = bean;

		/**
		 * 如果存在 InstantiationAwareBeanPostProcessor,則周遊執行 
		 * 		getEarlyBeanReference,該過程可能傳回一個 代理對象
		 */
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (SmartInstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().smartInstantiationAware) {
				exposedObject = bp.getEarlyBeanReference(exposedObject, beanName);
			}
		}
		return exposedObject;
	}
           

doCreateBean

方法中建立了對應

bean執行個體對象

後,在允許

循環依賴

的情況下會緩存對應的

單例工廠

,該方法預設實作即

getEarlyBeanReference

  • 這裡如果存在

    InstantiationAwareBeanPostProcessor

    ,便會依此執行

    getEarlyBeanReference

    方法,即此處是有可能傳回

    代理對象

  • 此處建立出來的執行個體之後會被加入

    三級緩存

    ,以避免可能多次構造執行個體造成的性能損耗

populateBean

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 {
				return;
			}
		}

		/**
		 * 此處是調用所有的 InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation
		 * 		但凡有傳回 false,此處就 return 不繼續注入了,目前的預設實作都是 true
		 */
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
				if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
					return;
				}
			}
		}

		// 從 BeanDefinition 擷取 PropertyValues
		PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

		/**
		 * 解析注入模式
		 * AUTOWIRE_BY_NAME:根據名稱注入
		 * AUTOWIRE_BY_TYPE:根據類型注入
		 * 一般情況 resolvedAutowireMode == AUTOWIRE_NO
		 */
		int resolvedAutowireMode = mbd.getResolvedAutowireMode();
		if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
			MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
			if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
				autowireByName(beanName, mbd, bw, newPvs);
			}
			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;
		/**
		 * 如果存在 InstantiationAwareBeanPostProcessor
		 * 則執行所有 InstantiationAwareBeanPostProcessor#postProcessProperties
		 * 		輔助完成屬性填充,諸如基于 @Autowired 等注解的屬性注入就發生在此處
		 */
		if (hasInstAwareBpps) {
			if (pvs == null) {
				pvs = mbd.getPropertyValues();
			}
			for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
				PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
				if (pvsToUse == null) {
					if (filteredPds == null) {
						filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
					}
					pvsToUse = bp.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);
		}
	}
           

核心方法:屬性填充,方法概括:

  • 填充前會執行所有

    InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation

    ,但凡有傳回

    false

    的就不再繼續,預設實作都是傳回

    true

  • 根據解析的

    AutowireMode

    處理

    名稱注入

    類型注入

    兩種情況,一般情況下注入模式是

    AUTOWIRE_NO

    ,即不進行上述處理
  • 執行所有

    InstantiationAwareBeanPostProcessor#postProcessProperties

    來輔助完成順序填充,其中的代表處理器有

    AutowiredAnnotationBeanPostProcessor

    CommonAnnotationBeanPostProcessor

    :基于

    @Autowired

    @Value

    等注解進行屬性注入
  • 最後基于

    BeanWrapper

    和上述

    PropertyValues

    進行屬性填充

initializeBean

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {

		/**
		 * invokeAwareMethods:
		 * 執行 BeanNameAware BeanClassLoaderAware BeanFactoryAware 回調
		 */
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				invokeAwareMethods(beanName, bean);
				return null;
			}, getAccessControlContext());
		}
		else {
			invokeAwareMethods(beanName, bean);
		}

		/**
		 * 執行所有 BeanPostProcessor#postProcessBeforeInitialization:初始化前處理
		 */
		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		try {
			/**
			 * 初始化:
			 * 1)InitializingBean#afterPropertiesSet
			 * 2)init-method 回調
			 */
			invokeInitMethods(beanName, wrappedBean, mbd);
		}
		catch (Throwable ex) {
			
		}
		/**
		 * 執行所有 BeanPostProcessor#postProcessAfterInitialization:初始化後處理
		 */
		if (mbd == null || !mbd.isSynthetic()) {
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

		return wrappedBean;
	}
           

此時的

bean執行個體

已構造完成并且填充好屬性,

執行個體化

完成并進入

初始化

階段:

  • 初始化前處理:執行所有

    BeanPostProcessor#postProcessBeforeInitialization

    方法
  • 初始化操作主要是:1)執行所有實作了

    InitializingBean

    接口的

    afterPropertiesSet

    方法 2)執行所有

    init-method

    ,比如

    @Bean

    注解上指定的、

    @PostConstruct

    注解标注的方法 等
  • 初始化後處理:執行所有

    BeanPostProcessor#postProcessAfterInitialization

    方法

其他方法

AbstractAutowireCapableBeanFactory

實作了

AbstractBeanFactory

定義的抽象方法

createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)

,它基于

容器

掃描的

BeanDefinition

提供了全生命周期

bean執行個體

的構造,包括

bean執行個體對象

的構造、各種後處理回調的執行、屬性的填充、初始化操作 等

同時,作為

AutowireCapableBeanFactory

接口的實作,它對各生命周期的實作也是分離開的,并暴露出對應的方法供以調用,譬如:

@Override
	@SuppressWarnings("unchecked")
	public <T> T createBean(Class<T> beanClass) throws BeansException {
		RootBeanDefinition bd = new RootBeanDefinition(beanClass);
		// 預設原型
		bd.setScope(SCOPE_PROTOTYPE);
		bd.allowCaching = ClassUtils.isCacheSafe(beanClass, getBeanClassLoader());
		return (T) createBean(beanClass.getName(), bd, null);
	}
           

基于給定

Class

構造

RootBeanDefinition

,來建立

bean執行個體

@Override
	public void autowireBean(Object existingBean) {
		RootBeanDefinition bd = new RootBeanDefinition(ClassUtils.getUserClass(existingBean));
		bd.setScope(SCOPE_PROTOTYPE);
		bd.allowCaching = ClassUtils.isCacheSafe(bd.getBeanClass(), getBeanClassLoader());
		BeanWrapper bw = new BeanWrapperImpl(existingBean);
		initBeanWrapper(bw);
		populateBean(bd.getBeanClass().getName(), bd, bw);
	}
           

給定執行個體填充屬性并執行初始化操作

等等

總結

  • 作為

    AbstractBeanFactory

    的子類,

    AbstractAutowireCapableBeanFactory

    實作了核心抽象方法

    createBean

    ,該方法用于構造一個執行全生命周期的

    bean執行個體

  • 作為

    AutowireCapableBeanFactory

    的實作類,

    AbstractAutowireCapableBeanFactory

    提供了

    各階段生命周期

    的細粒度實作,比如熟悉的

    applyBeanPostProcessorsAfterInitialization

    方法等

上一篇:【源碼】Spring —— BeanFactory 解讀 2 AbstractBeanFactory

下一篇:【源碼】Spring —— BeanFactory 解讀 4 關于循環依賴

繼續閱讀