文章目录
前言
在此继续分析spring源码,上一篇讲到了ApplicationContext.refresh里的基础语句。今天进入比较重要的阶段:
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
一、BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor是什么
此处不做过多介绍,想理解这个具体作用的,可以参见这篇拙作
二、Spring执行这些PostProcessor的步骤
1. BeanDefinitionRegistryPostProcessor优先级高
从invokeBeanFactoryPostProcessors一路debug下去,会到PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors,这也是Spring初始执行BeanFactoryPostProcessor的精髓了。
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
else {
regularPostProcessors.add(postProcessor);
}
}
可以发现把传进来的BeanPostProcessor,凡是BeanDefinitionPostProcessor类型的,先执行一遍,同时放到registryProcessors里面,而普通的BeanFactoryPostProcessor放入到regularPostProcessors里面
2. 开始执行Spring容器里的BeanDefinitionRegistryPostProcessor
2.1 执行了PriorityOrder接口的BeanDefinitionRegistryPostProcessor
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
// 筛选实现了PriorityOrdered接口的
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
// 注意此处的getBean,其实已经开始使用IOC的bean实例化周期了
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
// 防止某个BeanFactoryPostProcessor被重复执行,所以获取了的,就保存起来
processedBeans.add(ppName);
}
}
// 排序,其实此处Spring容器就提供了一个ConfigurationClassPostProcessor,所以排序方法,其实没走实现
// 而且这个类的getOrder方法返回的是Integer.MAX_VALUE
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
// 调用BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
2.2 ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry
这个方法也就是Spring中的重中之重了。
这个方法里调用了processConfigBeanDefinitions
// 获取已放入到容器中的所有BeanDefinition的name,我们的xxxApplication当然在里面
String[] candidateNames = registry.getBeanDefinitionNames();
for (String beanName : candidateNames) {
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
// 此处判断BeanDef上的某个标记CONFIGURATION_CLASS_ATTRIBUTE是否存在
if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {
// log
}
/**
* 实际上进行进行该标记的处理逻辑在此,其实就是区分了下@Configuration的重要地位,加了这个注解的
* CONFIGURATION_CLASS_ATTRIBUTE被标记为full,而加了@Component、@ComponentScan、@Import
* @ImportResource、@Bean注解的CONFIGURATION_CLASS_ATTRIBUTE被设置为lite
* 此处该标记的作用其实还是蛮重要的,只不过大多数时候我们写代码不会触发其出问题
**/
else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}
2.3 ConfigurationClassParser
parser.parse(candidates);方法里完成了BeanDefinition的扫描以及register,其实在这篇文章里面为了介绍@EnableAutoConfiguration的实现逻辑时,我们已经做了大概流程的梳理。不过下一篇可以详细梳理下。
总结
这一篇内容较少,最近耐心不足。需要坚持~