invokeBeanFactoryPostProcessors 执行过程分析
invokeBeanFactoryPostProcessors 这个方法实现非常长,但是基本处理过程很简单,存在很多重复的步骤。为了方便理解整个过程,这里还是有必要贴一下代码,代码中会详细标注所做的事情是什么,这个过程是构建 BeanFactory 非常重要一步。掌握这个过程,就可以随意玩转 BeanFactoryPostProcessor 了。
// Invoke BeanDefinitionRegistryPostProcessors first, if any.
Set<String> processedBeans = new HashSet<>();
// 当前 beanFactory 是否是 BeanDefinitionRegistry 类型
// 只有是 BeanDefinitionRegistry 类型,才具备注册 beanDefinition 的能力
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
// 普通的 BeanFactoryPostProcessor 集合
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
// BeanDefinitionRegistryPostProcessor 类型处理器集合
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
// 这里 beanFactoryPostProcessors 是在 SharedMetadataReaderFactoryContextInitializer 中加进来的,是 Spring 自己的处理器
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
// 如果是 BeanDefinitionRegistryPostProcessor 类型,就加到 registryProcessors
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
// 执行 BeanDefinitionRegistryPostProcessor 后置处理
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
else {
// 否则就放到 regularPostProcessors
regularPostProcessors.add(postProcessor);
}
}
// 不要在这里初始化 FactoryBeans:需要保留所有未初始化的常规bean,以使 beanFacotryPostProcessor 对其处理!
// 分离实现 PriorityOrdered,Ordered和其余优先级的 BeanDefinitionRegistryPostProcessor。
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// 首先,调用实现 PriorityOrdered 的 BeanDefinitionRegistryPostProcessors。
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
// 遍历 BeanDefinitionRegistryPostProcessors
for (String ppName : postProcessorNames) {
// 只处理实现 PriorityOrdered 接口的 BeanDefinitionRegistryPostProcessor
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
// 符合上述条件的 BeanDefinitionRegistryPostProcessor 放到 currentRegistryProcessors 中,供后面使用
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
// 标记当前 postProcessor 已经处理过了
processedBeans.add(ppName);
}
}
// 排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
// 调用 BeanDefinitionRegistryPostProcessor 后置处理器
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
// 接下来,调用实现 Ordered的BeanDefinitionRegistryPostProcessors
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();
}
// 现在,调用到目前为止已处理的所有处理器的 postProcessBeanFactory 回调。
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
else {
// 调用在上下文实例中注册的工厂处理器。就是前面提到的 SharedMetadataReaderFactoryContextInitializer 中注册的
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
// 这里再次拿到所有的 BeanFactoryPostProcessor
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// 同样将实现 PriorityOrdered、Order 和普通的 BeanFactoryPostProcessor 分离开
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
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);
}
}
// 首先,调用实现PriorityOrdered的BeanFactoryPostProcessors。
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
// 优先执行实现 PriorityOrdered 接口的 BeanFactoryPostProcessor
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// 接下来,调用实现Ordered的BeanFactoryPostProcessors。
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
// 执行实现 Ordered 接口的 BeanFactoryPostProcessor
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// 最后,调用所有其他 BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
// 执行其他没有实现任何优先级接口的 BeanFactoryPostProcessor
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
// 清除缓存的合并 beanDefinition,因为后处理器可能已经修改了原始元数据
beanFactory.clearMetadataCache();
}
上面代码段中大体就是,先处理 BeanDefinitionRegistryPostProcessor 类型的 BeanFactoryPostProcessor ,然后再处理普通的 BeanFactoryPostProcessor;在这里处理过程中,会根据一些排序规则来调整各个 BeanFactoryPostProcessor 的执行顺序。
这里先处理 BeanDefinitionRegistryPostProcessor 类型的 BeanFactoryPostProcessor 是一定的,因为需要在这个阶段去注册 BeanDefinition。在 classpath 下的所有 BeanDefinition 都被注册之后,再执行普通 BeanFactoryPostProcessor 的后置回调,这样就可以覆盖所有的 BeanDefinition。
invokeBeanDefinitionRegistryPostProcessors 执行过程分析
在第一次调用 invokeBeanDefinitionRegistryPostProcessors 时,当前的 BeanDefinitionRegistryPostProcessor 只有一个,就是 org.springframework.context.annotation.ConfigurationClassPostProcessor 。
在 ConfigurationClassPostProcessor 类中,会解析 @Configuration、@ComponentScan、@ComponentScans、@Import 等注解。ConfigurationClassPostProcessor 实现了 BeanDefinitionRegistryPostProcessor 接口,而 BeanDefinitionRegistryPostProcessor 接口继承了 BeanFactoryPostProcessor 接口,所以 ConfigurationClassPostProcessor 中需要重写 postProcessBeanDefinitionRegistry() 方法和 postProcessBeanFactory() 方法。而 ConfigurationClassPostProcessor 类的作用就是通过这两个方法去实现的。更多细节可以参考 ConfigurationClassPostProcessor源码解析 这篇文章,写的非常 nice。
invokeBeanDefinitionRegistryPostProcessors 处理的核心过程如下:
- 1、ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry:BeanDefinition 触发加载的入口
- 2、ConfigurationClassPostProcessor#processConfigBeanDefinitions:解析配置类,在此处会解析配置类上的注解(ComponentScan扫描出的类,@Import注册的类,以及@Bean方法定义的类)
- 3、ComponentScanAnnotationParser#parse:根据注解的属性值来过滤加载 classpath 下的 beanDefinition(默认条件就是 basePackages,默认的 basePackages 为当前启动类的根包)
- 4、ClassPathBeanDefinitionScanner#doScan:处理 basePackages 下所以的 beanDefinition,被打了 @Service、@Compoment 等注解的类都会被解析到
- 5、DefaultListableBeanFactory#registerBeanDefinition:将 beanDefinition 注册到 BeanFactory 中(beanDefinitionMap 中)
BeanFactoryPostProcessor 对 BeanDefinition 的修改
实现了一个 BeanFactoryPostProcessor ,没有实现任何排序接口。这个 TestBeanServiceBeanFactoryPostProcessor 的作用是将原来的 TestBeanService 修改为 ProxyTestBeanService。代码如下:
public class TestBeanServiceBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
// 根据类型拿到所有的 beanNames
Iterable<String> beanNames = getBeanNames(beanFactory, TestBeanService.class);
// 这里因为只有一个 TestBeanService ,所以只处理第一个
beanNames.forEach(beanName -> {
System.out.println("begin to execute BeanFactoryPostProcessor...");
BeanDefinitionRegistry beanDefinitionRegistry = (BeanDefinitionRegistry) beanFactory;
// 先从工程中拿到原始 beanDefinition
BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
// 这里构建一个新的 BeanDefinition,类型为 ProxyTestBeanService,ProxyTestBeanService 是 TestBeanService 的子类
RootBeanDefinition proxy = new RootBeanDefinition(ProxyTestBeanService.class);
// 这里设置指定的initMethod
proxy.setInitMethodName(beanDefinition.getInitMethodName());
// 设置一些属性
proxy.setPropertyValues(beanDefinition.getPropertyValues());
proxy.setPrimary(beanDefinition.isPrimary());
proxy.setRole(BeanDefinition.ROLE_APPLICATION);
// 将原始 beanDefinition 移除掉
beanDefinitionRegistry.removeBeanDefinition(beanName);
// 将代理的新的 beanDefinition 注册进去
beanDefinitionRegistry.registerBeanDefinition(beanName,proxy);
System.out.println("current bean type is : " + proxy.getBeanClass().getTypeName());
return;
});
}
}