BeanDefinitionRegistryPostProcessor、BeanFactoryPostProcessor初始化接口源码解析

BeanFactoryPostProcessor:

  • 作用:

以下由google翻译:

应用程序上下文可以在其bean定义中自动检测BeanFactoryPostProcessor bean,并在创建任何其他bean之前应用它们。

对于定制配置文件非常有用,这些文件针对系统管理员,覆盖应用程序上下文中配置的bean属性

  • 执行流程

执行BeanFactoryPostProcessor接口由org.springframework.context.support.PostProcessorRegistrationDelegate实现,将执行

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

首先进入判断

if (beanFactory instanceof BeanDefinitionRegistry) {
   // 省略代码
}

spring默认beanFactory为org.springframework.beans.factory.support.DefaultListableBeanFactory,符合条件

    1.执行传入参数beanFactoryPostProcessors

    2.执行实现BeanDefinitionRegistryPostProcessor接口与PriorityOrdered的实例

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);

    3.代码相同,执行实现BeanDefinitionRegistryPostProcessor接口与Ordered的实例

postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);//查询实现BeanDefinitionRegistryPostProcessor接口类
for (String ppName : postProcessorNames) {
    if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {//判断是否实现Ordered接口
        currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
        processedBeans.add(ppName);
    }
}
...//排序并执行相应方法

    4.执行未实现PriorityOrdered与Ordered接口的剩余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;
        }
    }
}
...//排序并执行相应方法

5.

执行BeanDefinitionRegistryPostProcessor的父类BeanFactoryPostProcessor接口实现方法postProcessBeanFactory

invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);

若第一步中beanFactory不是BeanDefinitionRegistry的实现类时

则会将传入的实现BeanFactoryPostProcessor接口的的实现方法全部执行


自此,实现了BeanDefinitionRegistryPostProcessor接口的实现类均已初始化完毕。

还没完

5.获得beanFactory中所有实现了BeanFactoryPostProcessor接口的bean(此时是包含上面已初始化完的示例)

String[] postProcessorNames =
				beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

6.根据相同的顺序将获得的实例(跳过已执行方法的实例)

for (String ppName : postProcessorNames) {
	if (processedBeans.contains(ppName)) {
		// 跳过已执行方法的实例
	}
	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);
	}
}

随后按相同顺序排序并执行。


结论:

1.执行BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法

  • BeanDefinitionRegistryPostProcessor+PriorityOrdered
  • BeanDefinitionRegistryPostProcessor+Ordered
  • 剩余BeanDefinitionRegistryPostProcessor

2.执行BeanFactoryPostProcessor的postProcessBeanFactory方法(与1中排序相同)

3.执行实现BeanFactoryPostProcessor接口实例


spring核心配置文件扫描是在这一层实现的,原理及修改例子请看下章

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值