spring源碼分析——BeanDefinitionRegistryPostProcessor接口與BeanFactoryPostProcessor接口


 

一:BeanDefinitionRegistryPostProcessor 與BeanFactoryPostProcessor接口

  這個接口支持自定義beanDefinition的注冊,在標准的注冊完成后(解析xml或者注解),在與實例化對象之前,實現這個接口

可以向beanDefinitionMap中注冊自定義的beanDefinition,這個接口從定義上看更多的是關注注冊。

 

1:實現beanDefinitionRegistryPostProcessor接口,重寫postProcessBeanDefinitionRegistry方法,在方法內創建beanDefinition對象,然后注冊到beanDefinitionRegistry中

 

創建一個pojo對象BeanDemo,用於測試在接口中注冊自定義beanDefinition

public class BeanDemo {

	private String name = "hello";

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@Override
	public String toString() {
		final StringBuffer sb = new StringBuffer("BeanDemo{");
		sb.append("name='").append(name).append('\'');
		sb.append('}');
		return sb.toString();
	}
}

  

@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {

	public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
		System.out.println("MyBeanDefinitionRegistryPostProcessor: "+registry);

		// 向beanDefinitionMap中注冊自定義的beanDefinition對象
		GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
		beanDefinition.setBeanClass(BeanDemo.class);
		registry.registerBeanDefinition("beanDemo",beanDefinition);
	}

	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		System.out.println("MyBeanDefinitionRegistryPostProcessor: "+beanFactory);
	}

}

  

 

 

 

成功的從spring容器中拿到了對象:

 

 

 

 

 

 

2:BeanFactoryPostProcessor接口

  這個接口支持修改容器內的beanDefinition對象,也可以直接注冊bean對象,在標准的beanDefinition注冊之后以及預實例化bean對象之前

 

 

 

 

通過運行結果可以看出beanDefinition在postProcessBeanFactory方法中被修改:

 

 

 

 

 

 

 

 

 

 

 

 在beanFactoryPostProcessor接口中注冊對象后,可以在spring中獲取到。

 

二:從源碼層面分析接口調用

refresh方法中invokeBeanFactoryPostProcessors:

 

 

 

 

 

 

 

主要的核心邏輯都在這個方法內:

 

 

 

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

		// Invoke BeanDefinitionRegistryPostProcessors first, if any.
		// 如果存在BeanDefinitionRegistryPostProcessor類型對象,要先調用
		Set<String> processedBeans = new HashSet<>();

		if (beanFactory instanceof BeanDefinitionRegistry) {
			BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
			List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
			List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

			// 第一次進來beanFactoryPostProcessors集合為空,不會走進來
			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.
			/**
			 * 不要在這里初始化FactoryBean類型的對象,不要初始化post-Processor對象,要把
			 * PriorityOrdered類型和Ordered類型以及剩下的分開
			 */
			List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

			// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
			/**
			 * 1: 根據類型找到所有實現BeanDefinitionRegistryPostProcessor接口的beanName
			 * 2: 遍歷所有beanName,判斷是否是PriorityOrdered接口的實例
			 * 3: 如果是則 getBean實例化這個對象,然后放入processedBean集合中
			 *
			 * 在這里getBeanNamesForType 會把字父類的beanDefinition合並Merge,得到RootBeanDefinition
 			 */
			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);
				}
			}

			/**
			 * 1:對currentRegistryProcessors集合內實例對象排序
			 * 2: 將排序過的集合添加到注冊集合registryProcessors中
			 * 3:調用currentRegistryProcessors集合中對象方法
			 * 4:清空當前注冊對象集合currentRegistryProcessors
			 */
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			registryProcessors.addAll(currentRegistryProcessors);
			// 調用注冊對象方法
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
			currentRegistryProcessors.clear();

			// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
			/**
			 * 在這里步驟和上一步類似,只不過這里操作的是實現Ordered接口的類
			 */
			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.
			/**
			 * 還是重復上面的動作,不過這次是排除掉上面已經調用過的實例(實現PriorityOrdered和Ordered接口)
			 */
			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;
					}
				}
				sortPostProcessors(currentRegistryProcessors, beanFactory);
				registryProcessors.addAll(currentRegistryProcessors);
				invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
				currentRegistryProcessors.clear();
			}

			// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
			/**
			 * 在這里,調用上面已經處理過的所有處理器的postProcessBeanFactory回調方法
			 */
			invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
			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!
		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) {
			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.
		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();
	}

  

實例化並調用實現PriorityOrdered接口的BeanDefinitionRegistryPostProcessor實現對象:

 

 

 

調用接口:

 

 

 實例化並調用實現Ordered接口的BeanDefinitionRegistryPostProcessor實現對象:

操作和剛才類似,只不過這次是調用實現Ordered接口的實現對象

 

 

 

 實例化其他的BeanDefinitionRegistryPostProcessor實現對象:

 

 

 

因為BeanDefinitionRegistryPostProcessor接口繼承了 BeanFactoryPostProcessor接口,所以也是BeanFactoryPostProcessor的子類

 

 

 

把剛才已經調用過BeanDefinitionRegistryPostProcessor接口的對象,在調用BeanFactoryPostProcessor接口

 

 

 

 

 

 

到這里 實現BeanDefinitionRegistryPostProcessor接口的對象都調用了 BeanFactoryPostProcessor 的實現類,但是還有單獨只實現了 BeanFactoryPostProcessor 接口的,

而沒有實現  BeanDefinitionRegistryPostProcessor 的,也需要調用 postProcessorBeanFactory方法:

 

 

實例化並調用對象:

 

 

到這里所有實現BeanFactoryPostProcessor接口的類都實例化並調用過了。

 

總結:這兩個接口是在標准的加載解析,生成BeanDefinition對象完成注冊后,非懶加載的對象預實例化之前 ,預留的后置接口,支持自定義BeanDefinition

然后實現注冊,BeanDefinitionRegistryPostProcessor側重於注冊信息,BeanFactoryPostProcessor側重於修改BeanDefinition對象的信息,也可以直接注冊bean對象。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM