spring 5.0.x源码学习系列五: AnnotationC

2021-03-18  本文已影响0人  avengerEug

前言

一、refresh源码黑箱理论

二、本篇博客的主角: invokeBeanFactoryPostProcessor方法

三、项目测试demo

3.1 项目结构

3.1.1 结构全景图

3.1.2 各类详情与作用

  1. 项目入口(启动spring环境的入口)


    在这里插入图片描述
  2. 全配置类, 定义扫描的包


    在这里插入图片描述
  3. 手动添加的BeanDefinitionRegistryPostProcessor


    在这里插入图片描述
  4. 手动添加的BeanFactoryPostProcessor


    在这里插入图片描述
  5. 由spring扫描出来的BeanDefinitionRegistryPostProcessor但无实现Ordered和PriorityOrdered接口


    在这里插入图片描述
  6. 由spring扫描出来的BeanDefinitionRegistryPostProcessor实现了Ordered接口, 且权重为1 => 权重低, 优先执行


    在这里插入图片描述
  7. 由spring扫描出来的BeanDefinitionRegistryPostProcessor实现了Ordered接口, 且权重为2 => 权重低, 优先执行


    在这里插入图片描述
  8. 由spring扫描出来的BeanDefinitionRegistryPostProcessor实现了PriorityOrdered接口, 且权重为1 => 权重低, 优先执行


    在这里插入图片描述
  9. 由spring扫描出来的BeanDefinitionRegistryPostProcessor实现了PriorityOrdered接口, 且权重为2 => 权重低, 优先执行


    在这里插入图片描述
  10. 由spring扫描出来的BeanFactoryPostProcessor


    在这里插入图片描述
  11. 由spring扫描出来的BeanFactoryPostProcessor实现了Ordered接口, 且权重为1 => 权重越低, 越优先执行


    在这里插入图片描述
  12. 由spring扫描出来的BeanFactoryPostProcessor实现了Ordered接口, 且权重为2 => 权重越低, 越优先执行


    在这里插入图片描述
  13. 由spring扫描出来的BeanFactoryPostProcessor实现了PriorityOrdered接口, 且权重为1 => 权重越低, 越优先执行


    在这里插入图片描述
  14. 由spring扫描出来的BeanFactoryPostProcessor实现了PriorityOrdered接口, 且权重为2 => 权重越低, 越优先执行


    在这里插入图片描述

3.2 执行流程及原理

3.2.1 处理手动添加的BeanFactoryPostProcessor(包含BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor)

在这里插入图片描述
在这里插入图片描述

3.2.2 执行BeanDefinitionRegistryPostProcessor类型且实现了PriorityOrdered接口的后置处理器

此步骤非常重要,后续将专门为此步骤总结一篇博客, 来具体描述它做了些什么事

在这里插入图片描述

3.2.3 执行BeanDefinitionRegistryPostProcessor类型且实现了Ordered接口的后置处理器, 执行过程与第二步大同小异

在这里插入图片描述

3.2.4 执行BeanDefinitionRegistryPostProcessor类型且未实现Ordered接口和PriorityOrdered接口的后置处理器, 执行过程与第三步大同小异

在这里插入图片描述

3.2.5 处理BeanDefinitionRegistryPostProcessor类型的BeanFactoryPostProcessor

```java
 // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
 // 这里是第一次调用手动添加到spring的BeanDefinitionRegistryPostProcessor的重写BeanFactoryPostProcessors接口的(postProcessBeanFactory)方法
 // 因为BeanDefinitionRegistryPostProcessor是继承BeanFactoryPostProcessor类。所以也重写了BeanFactoryPostProcessor的方法
 // 在第一次调用时只调用了BeanDefinitionRegisterPostProcessor中的方法
 invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
 // 这里是第一次调用手动添加到spring的BeanFactoryPostProcessor
 invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
```
![在这里插入图片描述](https://img.haomeiwen.com/i24982457/9a949fa03072b3e6?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

3.2.6 执行以@Component形式添加并实现了PriorityOrdered接口的BeanFactoryPostProcessor后置处理器

在这里插入图片描述

3.2.7 执行以@Component形式添加并实现了Ordered接口的BeanFactoryPostProcessor后置处理器

在这里插入图片描述

3.3 关于"3.2.3 执行BeanDefinitionRegistryPostProcessor类型且实现了Ordered接口的后置处理器, 执行过程与第二步大同小异"的两个疑问

问题 答案
Q1: 为什么这里也执行了实现PriorityOrdered接口的后置处理器?上面不是已经执行过了吗? 因为PriorityOrdered接口继承了Ordered接口, 所以在处理实现Ordered类型的接口时, 也会把实现PriorityOrdered接口的后置处理器也拿出来。同时之前的确已经执行过了实现了PriorityOrdered接口的后置处理器(ConfigurationClassPostProcessor), 但这是一个特殊的后置处理器, 因为它,我们才能在后面获取@Component注解形式添加的后置处理器。最重要的是在执行它的时候, bean工厂中只有一个实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor类型的后置处理器, 所以spring才用了processedBeans的set集合来存储已经执行过的后置处理器
Q2: 为什么只执行了postProcessorNames的2,3,4,5下标的后置处理器? 因为它们都实现了Ordered接口, 尽管有些后置处理器实现的是PriorityOrdered接口, 但PriorityOrdered接口继承了Ordered接口

三、小结

上一篇 下一篇

猜你喜欢

热点阅读