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
对于已经执行过的会跳过处理。
调用方法流程说明
- 调用BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry(registry)方法。参数beanFactoryPostProcessors传入的优先处理掉。然后获取容器注册的,对于这些Bean按照PriorityOrdered接口、Ordered、没有排序接口的实例分别进行处理。
- 调用BeanFactoryPostProcessor#postProcessBeanFactory(beanFactory)方法。备注:BeanDefinitionRegistryPostProcessor属于BeanFactoryPostProcessor子接口。先处理属于BeanDefinitionRegistryPostProcessor接口实例的postProcessBeanFactory(beanFactory)方法,然后获取容器注册的。对于这些Bean按照PriorityOrdered接口、Ordered、没有排序接口的实例分别进行处理。