Spring5源碼解析4-refresh方法之invokeBeanFactoryPostProcessors

invokeBeanFactoryPostProcessors(beanFactory);方法源碼以下:java

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
	// getBeanFactoryPostProcessors 獲取的是 this.beanFactoryPostProcessors;
	//this.beanFactoryPostProcessors 只能經過 AbstractApplicationContext.addBeanFactoryPostProcessor 方法添加
	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)
	if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
		beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
		beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
	}
}
複製代碼

getBeanFactoryPostProcessors()方法獲取的是AbstractApplicationContext#beanFactoryPostProcessors這個成員變量。git

這個成員變量只能經過代碼中手動編碼調用AbstractApplicationContext#addBeanFactoryPostProcessor方法來添加新的元素。很明顯,咱們這裏爲空。github

invokeBeanFactoryPostProcessors(beanFactory)方法的主要的邏輯在PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors方法中:spring

//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;
		List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
		List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

		//beanFactoryPostProcessors是傳進來裏的對象,把傳入的對象分類放入 BeanFactoryPostProcessor 和 BeanDefinitionRegistryPostProcessor
		//BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor ,是一個特殊的 BeanFactoryPostProcessor
		for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
			if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
				BeanDefinitionRegistryPostProcessor registryProcessor =
						(BeanDefinitionRegistryPostProcessor) postProcessor;
				//若是傳入的beanFactoryPostProcessors是它的子類,即:BeanDefinitionRegistryPostProcessor
				//則執行傳入的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法
				registryProcessor.postProcessBeanDefinitionRegistry(registry);
				registryProcessors.add(registryProcessor);
			} else {
				regularPostProcessors.add(postProcessor);
			}
		}

		// Do noitialize 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.
		List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

		// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.

		//這裏只能拿到spring內部的BeanDefinitionRegistryPostProcessor,
		//由於到這裏spring尚未去掃描Bean,獲取不到咱們經過@Component標識的自定義BeanDefinitionRegistryPostProcessor
		//通常默認狀況下,這裏只有一個,BeanName:org.springframework.context.annotation.internalConfigurationAnnotationProcessor
		//對應的BeanClass:ConfigurationClassPostProcessor
		String[] postProcessorNames =
				beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
		for (String ppName : postProcessorNames) {
			if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				//beanFactory.getBean, 這裏開始建立BeanDefinitionRegistryPostProcessor bean 了
				currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
				processedBeans.add(ppName);
			}
		}

		//排序
		sortPostProcessors(currentRegistryProcessors, beanFactory);

		// registryProcessors 中放的是 BeanDefinitionRegistryPostProcessor
		// 由於這裏只執行eanDefinitionRegistryPostProcessor中獨有的方法,而不會執行其父類即BeanFactoryProcessor的方法
		// 因此這裏須要把處理器放入一個集合中,後續統一執行父類的方法
		registryProcessors.addAll(currentRegistryProcessors);

		// 執行BeanDefinitionRegistryPostProcessor,currentRegistryProcessors中放的是spring內部的BeanDefinitionRegistryPostProcessor
		// 默認狀況下,只有 org.springframework.context.annotation.ConfigurationClassPostProcessor
		// ConfigurationClassPostProcessor 裏面就是在執行掃描Bean,而且註冊BeanDefinition
		invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);

		// 清空這個臨時變量,方便後面再使用
		currentRegistryProcessors.clear();

		// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
		// 這裏已經能夠獲取到咱們經過註冊到Spring容器的 BeanDefinitionRegistryPostProcessor 了
		postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
		for (String ppName : postProcessorNames) {
			// 以前優先處理的是實現PriorityOrdered接口的,而PriorityOrdered接口也實現了Ordered接口
			// 全部這裏須要把以前已經處理過的給過濾掉
			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);

		// 執行BeanDefinitionRegistryPostProcessor
		invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);

		//清空臨時變量
		currentRegistryProcessors.clear();

		// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
		boolean reiterate = true;
		while (reiterate) {
			reiterate = false;
			postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
				//執行沒有實現Ordered接口的BeanDefinitionRegistryPostProcessor
				if (!processedBeans.contains(ppName)) {
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
					reiterate = true;
				}
			}
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			registryProcessors.addAll(currentRegistryProcessors);
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
			currentRegistryProcessors.clear();
		}

		// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
		// List<BeanDefinitionRegistryPostProcessor> registryProcessors
		// 以前已經執行過BeanDefinitionRegistryPostProcessor獨有方法,如今執行其父類方法
		invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);

		// List<BeanFactoryPostProcessor> regularPostProcessors
		// 執行 BeanFactoryPostProcessor 方法
		invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
	} else {
		// Invoke factory processors registered with the context instance.
		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!
	// 獲取 BeanFactoryPostProcessor 的 beanName
	String[] postProcessorNames =
			beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

	// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
	// Ordered, and the rest.
	List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
	List<String> orderedPostProcessorNames = new ArrayList<>();
	List<String> nonOrderedPostProcessorNames = new ArrayList<>();
	for (String ppName : postProcessorNames) {
		// 若是已經被執行過了,就不在執行
		// 由於一開始先獲取的BeanDefinitionRegistryPostProcessor,而BeanDefinitionRegistryPostProcessor繼承了BeanFactoryPostProcessor
		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.
	// 根據不一樣的優先級,按序執行 BeanFactoryPostProcessor
	sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
	invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

	// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
	List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
	for (String postProcessorName : orderedPostProcessorNames) {
		orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
	}
	sortPostProcessors(orderedPostProcessors, beanFactory);
	invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

	// Finally, invoke all other BeanFactoryPostProcessors.
	List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
	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...
	beanFactory.clearMetadataCache();
}
複製代碼

源碼超級長,咱們慢慢來看。app

  1. Spring容器使用的BeanFactoryDefaultListableBeanFactory,它實現了BeanDefinitionRegistry接口,if條件成立。ide

  2. 優先處理程序傳進來的beanFactoryPostProcessors,也就是咱們手動調用AbstractApplicationContext#addBeanFactoryPostProcessor方法來添加的BeanFactoryPostProcessorpost

  3. BeanFactoryPostProcessor是一個頂級接口,他還有一個子類BeanDefinitionRegistryPostProcessor。在該方法中聲明瞭兩個List來存放BeanFactoryPostProcessorBeanDefinitionRegistryPostProcessor,以便控制這兩個接口方法的執行。學習

  4. 遍歷傳入的List<BeanFactoryPostProcessor> beanFactoryPostProcessors,將其分類放到兩個List中。若是傳入的是BeanDefinitionRegistryPostProcessor類,則先執行BeanDefinitionRegistryPostProcessor類中獨有的方法postProcessBeanDefinitionRegistry方法。固然,咱們這裏傳入的List<BeanFactoryPostProcessor> beanFactoryPostProcessors爲空。this

  5. 第一次執行beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);方法,從容器中獲取BeanDefinitionRegistryPostProcessor類型的Bean的name(這裏只是獲取名稱,尚未實例化Bean)。注意,程序執行到這裏,Spring尚未掃描包,尚未將項目中的Bean註冊到容器中。默認狀況下,這裏返回的數據爲以下圖所示。回憶一下,這個BeanDefinition是在何時被加入到BeanFactory的呢?是在AnnotationConfigApplicationContext的無參構造器中建立reader時註冊的BeanDefinition。其中BeanName爲org.springframework.context.annotation.internalConfigurationAnnotationProcessor,對應的Class爲org.springframework.context.annotation.ConfigurationClassPostProcessor編碼

    image.png

  6. 遍歷這個獲取的postProcessorNames,若是實現了PriorityOrdered接口,就調用beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)方法,從容器中獲取這個Bean,將其加入到臨時變量List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors中。

  7. currentRegistryProcessors中的元素進行排序,而後執行BeanDefinitionRegistryPostProcessor中的特有方法postProcessBeanDefinitionRegistry。注意哦,這裏沒有執行其父類的方法,而是又將其放到List<BeanDefinitionRegistryPostProcessor> registryProcessors中,到後面再執行其父類方法。

  8. 默認狀況下,此時currentRegistryProcessors中只有一個Bean即:org.springframework.context.annotation.ConfigurationClassPostProcessor(它實現了PriorityOrdered接口)。ConfigurationClassPostProcessor是一個很是重要的類,咱們後面在講。當程序執行完ConfigurationClassPostProcessorBeanDefinitionRegistryPostProcessor方法後,咱們程序中的Bean就被註冊到了Spring容器中了,須要注意的是,這裏還只是註冊了BeanDefinition,尚未建立Bean對象。

    currentRegistryProcessors

    ((DefaultListableBeanFactory) registry).beanDefinitionMap

  9. 當第二次執行postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);方法,此時由於以前已經完成了Bean的掃描,因此若是咱們有自定義的BeanDefinitionRegistryPostProcessor就能夠在這裏被獲取了。獲取以前,判斷其是否實現Ordered接口,而且以前沒有被執行過,則調用getBean方法,從容器中獲取該Bean,而後進行排序,執行postProcessBeanDefinitionRegistry方法。

  10. 前面已經按順序執行了實現PriorityOrderedOrdered接口的BeanDefinitionRegistryPostProcessor,最後,執行沒有實現Ordered接口的BeanDefinitionRegistryPostProcessorpostProcessBeanDefinitionRegistry方法。執行完以後再BeanDefinitionRegistryPostProcessor的父類方法postProcessBeanFactory

  11. 獲取容器中尚未被執行過的實現BeanFactoryPostProcessor接口的Bean,而後按順序執行的postProcessBeanFactory。默認狀況下,這裏會獲取到:

postProcessorNames

因爲Bean org.springframework.context.annotation.internalConfigurationAnnotationProcessor(對應的Class爲org.springframework.context.annotation.ConfigurationClassPostProcessor)在以前已經被執行了,這裏只會執行Bean org.springframework.context.event.internalEventListenerProcessor(對應的Class爲org.springframework.context.event.EventListenerMethodProcessor)的postProcessBeanFactory方法,源碼以下:

//org.springframework.context.event.EventListenerMethodProcessor#postProcessBeanFactory 源碼
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
	this.beanFactory = beanFactory;

	Map<String, EventListenerFactory> beans = beanFactory.getBeansOfType(EventListenerFactory.class, false, false);
	List<EventListenerFactory> factories = new ArrayList<>(beans.values());
	AnnotationAwareOrderComparator.sort(factories);
	this.eventListenerFactories = factories;
}
複製代碼

未完待續......

源碼學習筆記:github.com/shenjianeng…

歡迎各位關注公衆號,你們一塊兒學習成長。

Coder小黑
相關文章
相關標籤/搜索