1. 程式人生 > 其它 >Spring Ioc原始碼分析系列--Ioc容器BeanFactoryPostProcessor後置處理器分析

Spring Ioc原始碼分析系列--Ioc容器BeanFactoryPostProcessor後置處理器分析

Spring Ioc原始碼分析系列--Ioc容器BeanFactoryPostProcessor後置處理器分析

前言

上一篇文章Spring Ioc原始碼分析系列--Ioc原始碼入口分析已經介紹到Ioc容器的入口refresh()方法,並且分析了refresh()方法裡面的前三個子方法分析了一下。還記得分析了什麼麼?估計早忘了分析了什麼,可以說是看了個寂寞。但是不要慌,看了忘肯定是正常的,需要回顧複習一下,最好做點筆記記錄一下,有自己的沉澱才會印象深刻。最好跟著程式碼自己除錯幾遍,紙上得來終覺淺,絕知此事要躬行

好了,這裡回顧一下上篇文章的內容。上篇文章主要分析了三個方法,prepareRefresh()

進行了一些容器啟動前的屬性設定,obtainFreshBeanFactory()方法完成了讀取配置檔案,該方法的實現會針對xml配置建立內部容器,該容器負責bean的建立與管理,會進行BeanDefinition的註冊,prepareBeanFactory(beanFactory)方法主要註冊一些容器中需要使用的系統bean,例如classloaderBeanFactoryPostProcessor等。

喝了雞湯看了回顧,接下來才是今天這篇文章的正文開始。

思考一個問題,Spring提供了非常良好的擴充套件性,那麼擴充套件性在哪裡體現?這個問題仁者見仁智者見智,但是把場景壓縮一下,壓縮到上一篇文章我們已經獲得了一個載入完成BeanDefinition

的容器上,我在統一的BeanDefinition載入完成後,我想修改某一個或者增加某一個BeanDefinition這時候怎麼實現呢?

對Spring熟悉點的讀者可能已經猜到,這時候就可以使用BeanFactoryPostProcessor後置處理器來完成這個操作了,那麼這篇文章會解決兩個疑問:

  • BeanFactoryPostProcessor是什麼以及如何使用?
  • BeanFactoryPostProcessor在原始碼裡的呼叫邏輯?

第一個疑問會通過一個例子來說明,第二個疑問會通過原始碼分析來闡述。廢話少說,先進行BeanFactoryPostProcessor介紹,然後還是使用上一篇文章的例子來實現用BeanFactoryPostProcessor

來替換UserService的實現。

BeanFactoryPostProcessor介紹

這是一個容器的鉤子方法,允許自定義修改應用程式上下文的 bean 定義,調整上下文底層 bean 工廠的 bean 屬性值。對於針對用系統管理員的自定義配置檔案覆蓋應用程式上下文中配置的 bean 屬性非常有效。BeanFactoryPostProcessor可以與 bean 定義互動和修改,但不能與 bean 例項互動。這樣做可能會導致過早的 bean 例項化,違反容器並導致意外的副作用。如果需要 bean 例項互動,請考慮改為實現 BeanPostProcessorApplicationContext 自動檢測其 bean 定義中的 BeanFactoryPostProcessor ,並在建立任何其他 bean 之前應用它們。 BeanFactoryPostProcessor 也可以通過程式設計方式註冊到 ConfigurableApplicationContext

這個類只有一個方法,入參為當前容器,下面來看一下postProcessBeanFactory()這個方法。

@FunctionalInterface
public interface BeanFactoryPostProcessor {

	/**
	 * Modify the application context's internal bean factory after its standard
	 * initialization. All bean definitions will have been loaded, but no beans
	 * will have been instantiated yet. This allows for overriding or adding
	 * properties even to eager-initializing beans.
	 *
	 * 在標準初始化之後修改應用程式上下文的內部 bean 工廠。
	 * 所有 bean 定義都將被載入,但還沒有 bean 被例項化。
	 * 這允許覆蓋或新增屬性,甚至是急切初始化的 bean。
	 *
	 * @param beanFactory the bean factory used by the application context
	 * @throws org.springframework.beans.BeansException in case of errors
	 */
	void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

}

可以看到這裡的操作空間是非常大的,直接把當前的容器傳入,意味著你可以在當前容器的基礎上做任何操作。就比如你天天看著女神,可望而不可即,但是某天通過一個傳送門,把女神送到了你家裡,你是不是可以為所欲為了,想幹什麼就幹什麼,例如你可以讓她穿你喜歡的衣服,吃你喜歡吃的東西等等。

程式碼例子

那下面就用程式碼實現一下。還是在上一篇文章Spring Ioc原始碼分析系列--Ioc原始碼入口分析的基礎上進行新增程式碼, 所有原始碼都可以在我的倉庫ioc-sourcecode-analysis-code-demo裡找到 。

首先新建一個ReplaceUserServiceImpl類實現UserService

/**
 * @author Codegitz
 * @date 2022/5/12 15:57
 **/
public class ReplaceUserServiceImpl implements UserService {
	@Override
	public User getUser(String name, String age) {
		User user = new User();
		user.setId("1");
		// 這裡更改了賦值
		user.setName("ReplaceUser-" + name);
		user.setAge(age);
		return user;
	}
}

接著用一個類實現BeanFactoryPostProcessor。可以看到我這裡的邏輯也非常簡單,就是判斷是否存在一個名為userServiceBeanDefinition,如果有則把它的實現替換為io.codegitz.service.impl.ReplaceUserServiceImpl

/**
 * @author Codegitz
 * @date 2022/5/12 16:01
 **/
public class ReplaceUserBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		if (beanFactory.containsBeanDefinition("userService")){
			BeanDefinition beanDefinition = beanFactory.getBeanDefinition("userService");
			beanDefinition.setBeanClassName("io.codegitz.service.impl.ReplaceUserServiceImpl");
		}
	}
}

後置處理器已經準備好,接下來把後置處理器註冊到容器裡,我程式碼例子採用的是xml方式。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

	<bean id="userService" class="io.codegitz.service.impl.UserServiceImpl"/>
	<!-- 註冊後置處理器 -->
	<bean id="processor" class="io.codegitz.processor.ReplaceUserBeanFactoryPostProcessor"/>
</beans>

到這裡一切都完成了,那麼就可以啟動引導類跑一下看看效果了。可以看到這裡的實現已經替換為ReplaceUserServiceImpl,說明我們的ReplaceUserBeanFactoryPostProcessor後置處理器是生效了,那麼是怎麼生效的呢?進入下一節的原始碼分析。

原始碼分析

上面已經通過一個例子實現了功能,那麼這個原始碼裡是怎麼實現的呢?這裡會銜接上一篇文章的原始碼分析,繼續在refresh()方法裡遊蕩。上一篇已經分析了前三個,這篇會繼續往下分析兩個方法,分別是postProcessBeanFactory(beanFactory)invokeBeanFactoryPostProcessors(beanFactory)invokeBeanFactoryPostProcessors(beanFactory)就是後置處理器的邏輯,銜接了上文的例子。好傢伙,互相銜接。

postProcessBeanFactory(beanFactory)

這是一個空方法,留給子類實現,主要是一些web相關的ApplicationContext會重寫這個方法,傳入的是當前容器,操作空間也是非常大的。由於是個空方法,這裡不再贅述。

	/**
	 * Modify the application context's internal bean factory after its standard
	 * initialization. All bean definitions will have been loaded, but no beans
	 * will have been instantiated yet. This allows for registering special
	 * BeanPostProcessors etc in certain ApplicationContext implementations.
	 *
	 * 在標準初始化之後修改應用程式上下文的內部 bean 工廠。
	 * 所有 bean 定義都已經被載入,但還沒有 bean 被例項化。
	 * 這允許在某些 ApplicationContext 實現中註冊特殊的 BeanPostProcessors 等。
	 *
	 * @param beanFactory the bean factory used by the application context
	 */
	protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
	}

invokeBeanFactoryPostProcessors(beanFactory)

接下來就進入了今天的重頭戲,跟進程式碼,可以看到主要的程式碼實現委託給了PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors())去實現。

	/**
	 * Instantiate and invoke all registered BeanFactoryPostProcessor beans,
	 * respecting explicit order if given.
	 * <p>Must be called before singleton instantiation.
	 *
	 * 例項化並呼叫所有已註冊的 BeanFactoryPostProcessor bean,如果給定順序,則按照順序去執行
	 * 所有的後置處理器必須在其他的單例bean例項化之前被呼叫
	 */
	//例項化並且呼叫所有BeanFactoryPostProcessor beans
	protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		// 這個方法會進行兩種操作
		// 1.把給定的 BeanFactoryPostProcessor 傳入執行
		// 2.自動掃描容器裡的所有的 BeanFactoryPostProcessor 執行
		PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

		// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
		// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
		// 檢測是否有用於型別匹配的臨時 ClassLoader 和 LoadTimeWeaver
		if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}
	}

跟進PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors())裡面的程式碼。這個方法比較長,但是邏輯卻非常簡單,跟著註釋看一下理解起來問題不大。

	public static void invokeBeanFactoryPostProcessors(
			ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

		// Invoke BeanDefinitionRegistryPostProcessors first, if any.
		Set<String> processedBeans = new HashSet<>();

		if (beanFactory instanceof BeanDefinitionRegistry) {
			BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
			// 常規的BeanFactoryPostProcessor後置處理器
			List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
			// 擴充套件註冊BeanDefinition的BeanDefinitionRegistryPostProcessor後置處理器
			List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

			// 根據型別放入不同的後置處理器列表裡
			for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
					BeanDefinitionRegistryPostProcessor registryProcessor =
							(BeanDefinitionRegistryPostProcessor) postProcessor;
					registryProcessor.postProcessBeanDefinitionRegistry(registry);
					registryProcessors.add(registryProcessor);
				}
				else {
					regularPostProcessors.add(postProcessor);
				}
			}

			// Do not initialize FactoryBeans here: We need to leave all regular beans
			// uninitialized to let the bean factory post-processors apply to them!
			// Separate between BeanDefinitionRegistryPostProcessors that implement
			// PriorityOrdered, Ordered, and the rest.
			// 這裡不會初始化FactoryBeans,因為先初始化了的話BeanFactoryPostProcessor就無法對已經初始化的bean生效了
			List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

			// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
			// 首先會呼叫實現了PriorityOrdered介面的BeanDefinitionRegistryPostProcessors
			String[] postProcessorNames =
					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
				if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			registryProcessors.addAll(currentRegistryProcessors);
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
			currentRegistryProcessors.clear();

			// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
			// 接下來呼叫實現了Ordered介面的BeanDefinitionRegistryPostProcessors
			postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
				if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			registryProcessors.addAll(currentRegistryProcessors);
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
			currentRegistryProcessors.clear();

			// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
			// 最後,呼叫沒有實現上述介面的BeanDefinitionRegistryPostProcessors
			boolean reiterate = true;
			while (reiterate) {
				reiterate = false;
				postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
				for (String ppName : postProcessorNames) {
					if (!processedBeans.contains(ppName)) {
						currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
						processedBeans.add(ppName);
						// 為啥這裡要再次把reiterate設定為true?
						// 因為這裡BeanDefinitionRegistryPostProcessor可能會註冊另外的BeanFactoryPostProcessor,
						// 所以需要迴圈去迭代,直到當前容器裡沒有BeanFactoryPostProcessor為止
						reiterate = true;
					}
				}
				sortPostProcessors(currentRegistryProcessors, beanFactory);
				registryProcessors.addAll(currentRegistryProcessors);
				// 這裡可能會繼續註冊BeanFactoryPostProcessor
				invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
				currentRegistryProcessors.clear();
			}

			// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
			// 前面已經處理完成了所有的 BeanDefinitionRegistryPostProcessor,
			// 接下來這兩個方法就是處理 BeanFactoryPostProcessor,
			// 注意這裡只是處理了方法傳入的 beanFactoryPostProcessors ,
			// 處理完這個後後續的邏輯還是會自動檢測當前容器裡所有的BeanFactoryPostProcessor,然後分類逐次呼叫
			invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
			invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
		}

		else {
			// Invoke factory processors registered with the context instance.
			// 如果給定的beanFactory不是BeanDefinitionRegistry,
			// 那麼就不需要進行前面呼叫 BeanDefinitionRegistryPostProcessor 的操作,
			// 直接呼叫給定的 beanFactoryPostProcessors
			invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
		}

		// Do not initialize FactoryBeans here: We need to leave all regular beans
		// uninitialized to let the bean factory post-processors apply to them!
		// 這裡的邏輯跟上面的 BeanDefinitionRegistryPostProcessor 處理邏輯類似
		String[] postProcessorNames =
				beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

		// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
		// Ordered, and the rest.
		// 按照不同的優先順序去分類 BeanFactoryPostProcessor
		List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
		List<String> orderedPostProcessorNames = new ArrayList<>();
		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
		for (String ppName : postProcessorNames) {
			// 如果第一階段以及處理過了,不再處理
			if (processedBeans.contains(ppName)) {
				// skip - already processed in first phase above
			}
			else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
			}
			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
				orderedPostProcessorNames.add(ppName);
			}
			else {
				nonOrderedPostProcessorNames.add(ppName);
			}
		}

		// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
		// 首先呼叫實現了 PriorityOrdered 介面的 BeanFactoryPostProcessor
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

		// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
		// 其次呼叫實現了 Ordered 介面的 BeanFactoryPostProcessor
		List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
		for (String postProcessorName : orderedPostProcessorNames) {
			orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		sortPostProcessors(orderedPostProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

		// Finally, invoke all other BeanFactoryPostProcessors.
		// 最後呼叫沒有實現上述介面的 BeanFactoryPostProcessor
		List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
		for (String postProcessorName : nonOrderedPostProcessorNames) {
			nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

		// Clear cached merged bean definitions since the post-processors might have
		// modified the original metadata, e.g. replacing placeholders in values...
		// 清除快取的 merged bean definitions 定義,因為後處理器可能已經修改了原始元資料,例如替換值中的佔位符...
		beanFactory.clearMetadataCache();
	}

這個方法主要做了以下幾件事:

  • 首先會判斷當前容器的型別是不是BeanDefinitionRegistry型別,如果是,則判斷給定的beanFactoryPostProcessors是否存在BeanDefinitionRegistryPostProcessor型別的後置處理器,如果有則執行postProcessBeanDefinitionRegistry()方法,進行BeanDefinition的註冊。接著會分別獲取當前容器裡實現了PriorityOrderedOrdered介面和沒有實現排序介面的BeanDefinitionRegistryPostProcessor,排序後依次執行。
  • 如果不是BeanDefinitionRegistry型別,則直接呼叫invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory)方法呼叫所有給定的BeanFactoryPostProcessor
  • 經過前面兩步,已經處理完成了給定了beanFactoryPostProcessors,這裡會去檢測執行容器裡存在的BeanFactoryPostProcessor。這裡也會按照PriorityOrderedOrdered介面以及沒有實現排序介面的順序去呼叫。
  • 最後會清空容器裡元資料的配置快取

這個方法的邏輯是比較簡單的,就是程式碼量比較大,需要耐心看完。

接下來看下里面的一些字方法的內容

sortPostProcessors()完成後置處理器排序

	private static void sortPostProcessors(List<?> postProcessors, ConfigurableListableBeanFactory beanFactory) {
		// 比較簡單,就是獲取一個比較器 Comparator ,至於 Comparator 的原理,可以自己去看下相關文章
		Comparator<Object> comparatorToUse = null;
		if (beanFactory instanceof DefaultListableBeanFactory) {
			comparatorToUse = ((DefaultListableBeanFactory) beanFactory).getDependencyComparator();
		}
		if (comparatorToUse == null) {
			comparatorToUse = OrderComparator.INSTANCE;
		}
		// 排序
		postProcessors.sort(comparatorToUse);
	}

invokeBeanDefinitionRegistryPostProcessors()呼叫所有的BeanDefinitionRegistryPostProcessor

這個方法也比較簡單,就是逐個呼叫一下BeanDefinitionRegistryPostProcessor後置處理器。

	/**
	 * Invoke the given BeanDefinitionRegistryPostProcessor beans.
	 * 呼叫給定的 BeanDefinitionRegistryPostProcessor bean。
	 */
	private static void invokeBeanDefinitionRegistryPostProcessors(
			Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {

		for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
			postProcessor.postProcessBeanDefinitionRegistry(registry);
		}
	}

invokeBeanFactoryPostProcessors()呼叫所有的BeanFactoryPostProcessor

逐個呼叫一下BeanFactoryPostProcessor後置處理器。

	/**
	 * Invoke the given BeanFactoryPostProcessor beans.
	 * 呼叫給定的 BeanFactoryPostProcessor bean。
	 */
	private static void invokeBeanFactoryPostProcessors(
			Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {

		for (BeanFactoryPostProcessor postProcessor : postProcessors) {
			postProcessor.postProcessBeanFactory(beanFactory);
		}
	}

beanFactory.getBeanNamesForType()根據型別獲取bean名稱

beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false)會根據傳入的型別獲取該型別所有的bean名稱。

跟進程式碼檢視,會呼叫doGetBeanNamesForType()方法進行獲取。

	public String[] getBeanNamesForType(@Nullable Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) {
		// 配置沒有凍結 || 型別為空 || 不允許提前初始化 則進入
		if (!isConfigurationFrozen() || type == null || !allowEagerInit) {
			return doGetBeanNamesForType(ResolvableType.forRawClass(type), includeNonSingletons, allowEagerInit);
		}
		Map<Class<?>, String[]> cache =
				(includeNonSingletons ? this.allBeanNamesByType : this.singletonBeanNamesByType);
		String[] resolvedBeanNames = cache.get(type);
		if (resolvedBeanNames != null) {
			return resolvedBeanNames;
		}
		// 允許提前初始化
		resolvedBeanNames = doGetBeanNamesForType(ResolvableType.forRawClass(type), includeNonSingletons, true);
		if (ClassUtils.isCacheSafe(type, getBeanClassLoader())) {
			cache.put(type, resolvedBeanNames);
		}
		return resolvedBeanNames;
	}

跟進doGetBeanNamesForType()方法,這個方法也比較長,但是邏輯也比較清晰,就是遍歷了beanDefinitionNames判斷是否符合型別要求,符合則返回。

	private String[] doGetBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit) {
		List<String> result = new ArrayList<>();

		// Check all bean definitions.
		// 從所有的 beanDefinitionNames 檢查所有符合型別要求的 bean ,加入 result
		for (String beanName : this.beanDefinitionNames) {
			// Only consider bean as eligible if the bean name
			// is not defined as alias for some other bean.
			// 如果 bean 名稱未定義為其他 bean 的別名,則該bean符合要求。
			if (!isAlias(beanName)) {
				try {
					// 獲取 beanName 的 RootBeanDefinition
					RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
					// Only check bean definition if it is complete.
					if (!mbd.isAbstract() && (allowEagerInit ||
							(mbd.hasBeanClass() || !mbd.isLazyInit() || isAllowEagerClassLoading()) &&
									!requiresEagerInitForType(mbd.getFactoryBeanName()))) {
						boolean isFactoryBean = isFactoryBean(beanName, mbd);
						BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();
						// 型別是否匹配
						boolean matchFound = false;
						boolean allowFactoryBeanInit = allowEagerInit || containsSingleton(beanName);
						boolean isNonLazyDecorated = dbd != null && !mbd.isLazyInit();
						// 主要就是呼叫 isTypeMatch() 方法判斷型別是否匹配
						if (!isFactoryBean) {
							if (includeNonSingletons || isSingleton(beanName, mbd, dbd)) {
								matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
							}
						}
						else  {
							if (includeNonSingletons || isNonLazyDecorated ||
									(allowFactoryBeanInit && isSingleton(beanName, mbd, dbd))) {
								matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
							}
							if (!matchFound) {
								// In case of FactoryBean, try to match FactoryBean instance itself next.
								beanName = FACTORY_BEAN_PREFIX + beanName;
								matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
							}
						}
						// 如果匹配則加入
						if (matchFound) {
							result.add(beanName);
						}
					}
				}
				catch (CannotLoadBeanClassException | BeanDefinitionStoreException ex) {
					// 省略部分異常處理..
				}
			}
		}


		// Check manually registered singletons too.
		// 檢查手動註冊的單例bean
		for (String beanName : this.manualSingletonNames) {
			try {
				// In case of FactoryBean, match object created by FactoryBean.
				if (isFactoryBean(beanName)) {
					if ((includeNonSingletons || isSingleton(beanName)) && isTypeMatch(beanName, type)) {
						result.add(beanName);
						// Match found for this bean: do not match FactoryBean itself anymore.
						continue;
					}
					// In case of FactoryBean, try to match FactoryBean itself next.
					beanName = FACTORY_BEAN_PREFIX + beanName;
				}
				// Match raw bean instance (might be raw FactoryBean).
				// 匹配則加入
				if (isTypeMatch(beanName, type)) {
					result.add(beanName);
				}
			}
			catch (NoSuchBeanDefinitionException ex) {
				// 省略部分異常...
			}
		}

		return StringUtils.toStringArray(result);
	}

到這裡BeanFactoryPostProcessor的原始碼呼叫以及相關的邏輯分析完了,是不是比較簡單。

小結

這篇文章主要是介紹了BeanFactoryPostProcessor後置處理器的使用和底層原理。文章開頭首先回顧了上一篇文章的內容,然後例子驅動分析,先用簡單的例子實現了BeanFactoryPostProcessor的使用,然後再進行了原始碼分析,整個文章下來思路是比較清晰的。那麼看到這裡,有沒有解決了文章開頭的兩個疑問?

  • BeanFactoryPostProcessor是什麼以及如何使用?
  • BeanFactoryPostProcessor在原始碼裡的呼叫邏輯?

如果沒有,那不怪你,可能是我寫得不好。

今天是汶川地震14週年,生命無常,向遇難的同胞寄託哀思,向參與救援的同胞致敬。

如果有人看到這裡,那在這裡老話重提。與君共勉,路漫漫其修遠兮,吾將上下而求索。