Spring Boot源码分析(4) -- BeanFactoryProcessor加载分析

Spring Boot源码分析(4) -- BeanFactoryProcessor加载分析

在SpringApplication分析中我们谈论到,在准备好ApplicationContext上下文后,调用了refresh方法。从上面的分析中可以看到,使用的是AnnotationConfigApplicationContext实例的上下文。这一篇的内容主要围绕refresh方法分析BeanFactoryProcessor。主要分析refresh方法中的invokeBeanFactoryPostProcessors(beanFactory)方法。

我们直接看invokeBeanFactoryPostProcessors(beanFactory),从方法名称来看,这个方法处理的是BeanFactoryPostProcessor接口的Bean。调用方法如下:

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
	// 调用BeanFactoryPostProcessor
	PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
	// 省略LoadTimeWeaver接口处理
}

可能你会好奇,getBeanFactoryPostProcessors()方法获取了哪些BeanFactoryPostProcessor?所有的BeanFactoryPostProcessor都保存在beanFactoryPostProcessors属性中,而添加是通过addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor)方法处理的。

public void addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor) {
	Assert.notNull(postProcessor, "BeanFactoryPostProcessor must not be null");
	this.beanFactoryPostProcessors.add(postProcessor);
}

运行调式发现,有以下几个BeanFactoryPostProcessor实例。

  • ConfigurationWarningsApplicationContextInitializer$ConfigurationWarningsPostProcessor
  • SharedMetadataReaderFactoryContextInitializer$CachingMetadataReaderFactoryPostProcessor
  • ConfigFileApplicationListener$PropertySourceOrderingPostProcessor

​是不是觉得这些类很熟悉,这些类就是我们在前面分析Spring Boot初始化器和监听器的时候说过的。

BeanFactoryPostProcessor处理过程

关于具体是如何处理BeanFactoryPostProcessor的,我们需要跟进到PostProcessorRegistrationDelegate的invokeBeanFactoryPostProcessors方法中去看。调用方法如下:

public static void invokeBeanFactoryPostProcessors(
		ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
	Set<String> processedBeans = new HashSet<String>();

	if (beanFactory instanceof BeanDefinitionRegistry) {
		BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
		// 普通的处理器
		List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
		// 注册用处理器
		List<BeanDefinitionRegistryPostProcessor> registryProcessors = new LinkedList<BeanDefinitionRegistryPostProcessor>();

		// 单独处理BeanDefinitionRegistryPostProcessor
		for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
			if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
				BeanDefinitionRegistryPostProcessor registryProcessor =
						(BeanDefinitionRegistryPostProcessor) postProcessor;
				registryProcessor.postProcessBeanDefinitionRegistry(registry);
				registryProcessors.add(registryProcessor);
			}
			else {
				regularPostProcessors.add(postProcessor);
			}
		}

		// 这里并不会初始化FactoryBean,所有普通的Bean不会初始化,而是让BeanFactoryPostProcessor应用于他们。
		// 对于BeanDefinitionRegistryPostProcessors,实现PriorityOrdered、Ordered接口的分开处理。
		List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();

		// 首先,获取实现PriorityOrdered接口的BeanDefinitionRegistryPostProcessor。
		// 当调用getBean方法时,就已经完成了这些Bean的加载。
		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中,获取到ConfigurationClassPostProcessor实例
		registryProcessors.addAll(currentRegistryProcessors);
		invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
		currentRegistryProcessors.clear();
		// 处理实现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();

		// 处理其他所有的BeanDefinitionRegistryPostProcessor
		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();
		}

		// 处理BeanFactoryPostProcessor
		invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
	}
	else {
		invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
	}

	// 省略对BeanFactoryPostProcessor接口的处理,处理方式和BeanDefinitionRegistryPostProcessor接口一样

调用流程说明

上面的代码很长,我们说一下其中的流程。

  • 首先,处理BeanDefinitionRegistryPostProcessor接口。优先处理通过参数beanFactoryPostProcessors传入的,然后处理容器注册进来的实例。处理的过程按照实现PriorityOrdered、Ordered、没有排序接口实现的顺序进行处理。

    上面已经说过,参数传入beanFactoryPostProcessors实例为:ConfigurationWarningsApplicationContextInitializer$ConfigurationWarningsPostProcessor、

    SharedMetadataReaderFactoryContextInitializer$CachingMetadataReaderFactoryPostProcessor、

    ConfigFileApplicationListener$PropertySourceOrderingPostProcessor。其中前两个实现了BeanDefinitionRegistryPostProcessor接口。

    注册获取的BeanDefinitionRegistryPostProcessor实例为:ConfigurationClassPostProcessor,这个类负责处理注解配置,后面单独分析。

  • 其次,处理BeanFactoryPostProcessor接口。处理原则和上面一致。

    先处理ConfigFileApplicationListener$PropertySourceOrderingPostProcessor,然后从注册获取到以下实例:ConfigurationClassPostProcessor、PropertySourcesPlaceholderConfigurer、ConfigurationPropertiesBindingPostProcessor.store

对于已经执行过的会跳过处理。

调用方法流程说明

  1. 调用BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry(registry)方法。参数beanFactoryPostProcessors传入的优先处理掉。然后获取容器注册的,对于这些Bean按照PriorityOrdered接口、Ordered、没有排序接口的实例分别进行处理。

  2. 调用BeanFactoryPostProcessor#postProcessBeanFactory(beanFactory)方法。备注:BeanDefinitionRegistryPostProcessor属于BeanFactoryPostProcessor子接口。先处理属于BeanDefinitionRegistryPostProcessor接口实例的postProcessBeanFactory(beanFactory)方法,然后获取容器注册的。对于这些Bean按照PriorityOrdered接口、Ordered、没有排序接口的实例分别进行处理。

转载于:https://my.oschina.net/xiaoqiyiye/blog/1624268

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值