Spring源碼系列:IOC容器的擴展

概述

Spring的核心就是容器思想,後續的所有的spring的功能都是在此基礎上進行擴展,談到擴展我們就不得不提spring爲我們預留的一些功能強大的擴展接口,也就是在設計開發IOC容器的時候爲後續功能或開發者預留的一些接口。
下面我們就來看看spring爲我們預留了哪些接口 他們在容器啓動的哪一步被調用。

BeanPostProcessor

BeanPostProcessor:這是一個所有擴展接口(除BeanFactoryPostProcessor)的父接口。該接口提供兩個方法

  • postProcessBeforeInitialization:在對象的初始化之前調用,IOC容器會將當前實例化的對象的引用和名字傳遞給該方法。
  • postProcessProperties:在對象的初始化之後調用,IOC容器會將當前正在實例化的對象的引用和名字傳遞給該方法

調用時機

//代碼片段1
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
			throws BeanCreationException {
	......		
	try {
	  populateBean(beanName, mbd, instanceWrapper);
	  exposedObject = initializeBean(beanName, exposedObject, mbd);
	}	catch (Throwable ex) {}
	......
}
//代碼片段2  上面的initializeBean方法
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
	if (System.getSecurityManager() != null) {
		AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
			invokeAwareMethods(beanName, bean);
			return null;
		}, getAccessControlContext());
	}
	else {
		invokeAwareMethods(beanName, bean);
	}
	Object wrappedBean = bean;
	if (mbd == null || !mbd.isSynthetic()) {
	//這裏調用所有 BeanPostProcessor的postProcessBeforeInitialization方法 並把當前的bean的引用和名字傳遞給該方法
	//如果有一個後置處理器返回了null 那麼後續的後置處理器將會跳過該方法
		wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
	}
	try {
	    //這裏實際上就是調用對象的afterPropertiesSet和init方法 順序調用
		invokeInitMethods(beanName, wrappedBean, mbd);
	}
	catch (Throwable ex) {
	}
	if (mbd == null || !mbd.isSynthetic()) {
	//這裏調用所有 BeanPostProcessor的postProcessAfterInitialization方法 並把當前的bean的引用和名字傳遞給該方法
	//如果有一個後置處理返回了null 後續的後置處理器將會跳過該方法
		wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
	}
	return wrappedBean;
}

可以看到上述的兩個方法是在spring實例化Bean的時候調用並且是在bean的初始化前後調用。

InstantiationAwareBeanPostProcessor

InstantiationAwareBeanPostProcessor:該接口繼承BeanPostProcessor。該接口也提供4個方法 其中一個已廢棄,作用於bean的實例化前後

  • postProcessBeforeInstantiation:在對象的實例化之前調用,IOC容器會將當前實例化的Class和名字傳遞給該方法。
  • postProcessAfterInstantiation:在對象的實例化之後調用,IOC容器會將當前正在實例化的對象的引用和名字傳遞給該方法
  • postProcessProperties: 在對象實例完成之後 初始化之前 可以動態設置實例屬性 可以參考AutowiredAnnotationBeanPostProcessor
    調用時機
    由於上面兩個方法的調用點 相對比較分散 所以下面將它們分開展示
    postProcessBeforeInstantiation:調用點:
//代碼片段1
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
		throws BeanCreationException {
	try {
	   //在這裏調用了postProcessBeforeInstantiation  可以看到這正是實例化bean之前
	   //下面一個if的條件判斷 意味着 如果我們該方法返回了一個當前class的實例 IOC將結束後面的流程。我們可以在這返回一個代理類。這樣我們就可以動態包裝springIoc容器中的bean
		Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
		if (bean != null) {
			return bean;
		}
	}
	catch (Throwable ex) {
	}
	//實例化bean
	Object beanInstance = doCreateBean(beanName, mbdToUse, args);
	return beanInstance;
}
//代碼片段2 進入resolveBeforeInstantiation
@Nullable
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
	Object bean = null;
	if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
		// Make sure bean class is actually resolved at this point.
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			Class<?> targetType = determineTargetType(beanName, mbd);
			if (targetType != null) {
			//這裏就會找到所有的InstantiationAwareBeanPostProcessor並調用postProcessBeforeInstantiation
				bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
				//如果返回了代理類 直接調用postProcessAfterInstantiation並結束實例化流程
				if (bean != null) {
					bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
				}
			}
		}
		mbd.beforeInstantiationResolved = (bean != null);
	}
	return bean;
}

postProcessAfterInstantiation:調用點:
該調用點分爲兩個地方,第一處是上面代碼調用了postProcessAfterInstantiation ,當postProcessBeforeInstantiation 返回代理類的時候 會立馬執行postProcessAfterInstantiation
第二處是正常流程實例完之後的調用

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
	if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			if (bp instanceof InstantiationAwareBeanPostProcessor) {
				InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
		//在填充bean之前調用postProcessAfterInstantiation 如果返回false結束bean的填充和初始化流程		
				if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
					return;
				}
			}
		}
	}
}

postProcessProperties調用點

 protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
	
	if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			if (bp instanceof InstantiationAwareBeanPostProcessor) {
				InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
				if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
					return;
				}
			}
		}
	}
	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;
	//這裏調用了屬性填充回調  可以看到是在postProcessAfterInstantiation調用之後		
				PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
				if (pvsToUse == null) {
					if (filteredPds == null) {
						filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
					}
				//該方法已被標記爲廢棄 postProcessProperties取代 這裏僅僅是對該方法做的兼容 相信在後續版本會去掉 	
					pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
					if (pvsToUse == null) {
						return;
					}
				}
				pvs = pvsToUse;
			}
		}
	}
}

MergedBeanDefinitionPostProcessor

**MergedBeanDefinitionPostProcessor:該接口繼承BeanPostProcessor。該接口提供一個方法,IOC容器會將當前正在實例化的對象的bean定義引用和Class對象以及bean名字傳遞給該方法。
調用時機
以下源碼省略了與本次討論無關的代碼

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
			throws BeanCreationException {
	
	BeanWrapper instanceWrapper = null;
	if (mbd.isSingleton()) {
		instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
	}
	if (instanceWrapper == null) {
	 //創建bean實例
		instanceWrapper = createBeanInstance(beanName, mbd, args);
	}
	final Object bean = instanceWrapper.getWrappedInstance();
	Class<?> beanType = instanceWrapper.getWrappedClass();
	if (beanType != NullBean.class) {
		mbd.resolvedTargetType = beanType;
	}
	synchronized (mbd.postProcessingLock) {
		if (!mbd.postProcessed) {
			try {
		//這裏調用了	postProcessMergedBeanDefinition 可以看到也是在創建bean實例之後調用 但是在populateBean和initBean之前調用
		//所以調用時機應該是介於InstantiationAwareBeanPostProcessor的兩個方法之間。
			applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
			}
			catch (Throwable ex) {
			}
			mbd.postProcessed = true;
		}
	}
	boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
			isSingletonCurrentlyInCreation(beanName));
	if (earlySingletonExposure) {
		if (logger.isTraceEnabled()) {
			logger.trace("Eagerly caching bean '" + beanName +
					"' to allow for resolving potential circular references");
		}
		addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
	}
	Object exposedObject = bean;
	try {
		populateBean(beanName, mbd, instanceWrapper);
		exposedObject = initializeBean(beanName, exposedObject, mbd);
	}
	catch (Throwable ex) {
	}
	return exposedObject;
	}

SmartInstantiationAwareBeanPostProcessor

SmartInstantiationAwareBeanPostProcessor:該接口繼承InstantiationAwareBeanPostProcessor。該接口也提供三個方法,作用於bean的實例化過程
-predictBeanType:從名字看是預測bean的類型。
-determineCandidateConstructors:判斷合適的bean的構造方法。
-getEarlyBeanReference:當bean 創建時,爲了防止後續有循環依賴,會提前暴露回調方法,用於 bean 實例化的後置處理,在提前暴露的回調方法中觸發。

predictBeanType 調用點


   //該方法是被isFactoryBean調用 判斷當前實例的Bean是否是FactoryBean  是在創建Bean的實例的方法中調用
	@Override
	@Nullable
	protected Class<?> predictBeanType(String beanName, RootBeanDefinition mbd, Class<?>... typesToMatch) {
		Class<?> targetType = determineTargetType(beanName, mbd, typesToMatch);

		// Apply SmartInstantiationAwareBeanPostProcessors to predict the
		// eventual type after a before-instantiation shortcut.
		if (targetType != null && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
					SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
			//這裏調用後置處理器的類型預測方法		
					Class<?> predicted = ibp.predictBeanType(targetType, beanName);
					if (predicted != null && (typesToMatch.length != 1 || FactoryBean.class != typesToMatch[0] ||
							FactoryBean.class.isAssignableFrom(predicted))) {
						return predicted;
					}
				}
			}
		}
		return targetType;
	}

determineCandidateConstructors 調用點


protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
          ......
	// 該擴展方法也是在bean實例化方法中調用 
	Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
	if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
			mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
		return autowireConstructor(beanName, mbd, ctors, args);
	}
	ctors = mbd.getPreferredConstructors();
	if (ctors != null) {
		return autowireConstructor(beanName, mbd, ctors, null);
	}
	return instantiateBean(beanName, mbd);
	}

getEarlyBeanReference調用點

//代碼片段1
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
			throws BeanCreationException {
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		final Object bean = instanceWrapper.getWrappedInstance();
		Class<?> beanType = instanceWrapper.getWrappedClass();
		if (beanType != NullBean.class) {
			mbd.resolvedTargetType = beanType;
		}
       ......
		boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
				isSingletonCurrentlyInCreation(beanName));
		if (earlySingletonExposure) {
			if (logger.isTraceEnabled()) {
				logger.trace("Eagerly caching bean '" + beanName +
						"' to allow for resolving potential circular references");
			}
			//這裏在創建完Bean之後 向三級緩存中(singletonFactories)放入一個ObjectFactory對象
			//而ObjectFactory回調了SmartInstantiationAwareBeanPostProcessor的getEarlyBeanReference方法得到了一個Bean的早期實例 這也是spring如何解決循環依賴的問題
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
		}
 ......
		return exposedObject;
	}
//代碼片段2
    //這裏是對所有的SmartInstantiationAwareBeanPostProcessor 的getEarlyBeanReference回調
   //從singletonFactories獲取緩存的ObjectFactory對象 之後調用 其getObject方法獲取當前的bean實例
   //一但調用getObject方法就會執行下面的回調方法 獲取一個提前暴露的bean的引用
	protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
		Object exposedObject = bean;
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
					SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
					exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
				}
			}
		}
		return exposedObject;
	}

BeanFactoryPostProcessor

**BeanFactoryPostProcessor:該接口是一個頂級接口。改接口及其子接口一般是對BeanFactory的擴展,一般用來在讀取所有的beanDefinition信息之後,實例化之前可以取修改一些BeanDefinition的信息。提供一個回調方法postProcessBeanFactory:.該方法會將BeanFactory引用傳遞回來。
調用點

// AbstractApplicationContext.refresh
@Override
	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			prepareRefresh();
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
			prepareBeanFactory(beanFactory);
			try {
				postProcessBeanFactory(beanFactory);
				//這裏會通過PostProcessorRegistrationDelegate代理類去最終調用postProcessBeanFactory方法
				invokeBeanFactoryPostProcessors(beanFactory);
				registerBeanPostProcessors(beanFactory);
				initMessageSource();
				initApplicationEventMulticaster();
				onRefresh();
				registerListeners();
				finishBeanFactoryInitialization(beanFactory);
				finishRefresh();
			}
			catch (BeansException ex) {
			}
		}
	}

BeanDefinitionRegistryPostProcessor

**BeanDefinitionRegistryPostProcessor:該接口是BeanFactoryPostProcessor的一個子接口。該接口也提供了一個擴展方法postProcessBeanDefinitionRegistry 接收一個BeanDefinitionRegistry引用。意味着 我們可以對beanDefinition註冊表去添加刪除更改。
調用點也是在PostProcessorRegistrationDelegate中的invokeBeanFactoryPostProcessors方法中。

public static void invokeBeanFactoryPostProcessors(
			ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
		Set<String> processedBeans = new HashSet<>();
		if (beanFactory instanceof BeanDefinitionRegistry) {
			BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
			List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
			List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

			for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
					BeanDefinitionRegistryPostProcessor registryProcessor =
							(BeanDefinitionRegistryPostProcessor) postProcessor;
			//這裏對所有的BeanDefinitionRegistryPostProcessor實現類的postProcessBeanDefinitionRegistry反方調用	
					registryProcessor.postProcessBeanDefinitionRegistry(registry);
					registryProcessors.add(registryProcessor);
				}
				else {
					regularPostProcessors.add(postProcessor);
				}
			}
}			

調用執行順序

  • BeanDefinitionRegistryPostProcessor:postProcessBeanDefinitionRegistry
  • BeanFactoryPostProcessor:postProcessBeanFactory
  • InstantiationAwareBeanPostProcessor:postProcessBeforeInstantiation
  • SmartInstantiationAwareBeanPostProcessor:determineCandidateConstructors
  • MergedBeanDefinitionPostProcessor:postProcessMergedBeanDefinition
  • InstantiationAwareBeanPostProcessor:postProcessAfterInstantiation
  • SmartInstantiationAwareBeanPostProcessor:getEarlyBeanReference
  • InstantiationAwareBeanPostProcessor:postProcessProperties
  • BeanPostProcessor:postProcessBeforeInitialization
  • BeanPostProcessor:postProcessAfterInitialization
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章