invokeBeanFactoryPostProcessors解析
基于注解启动的
方法:
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
//TODO
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
//.........
}
1.invokeBeanFactoryPostProcessors方法入参:beanFactory和getBeanFactoryPostProcessors()
beanFactory:
就是在obtainFreshBeanFactory()时返回的 ,其实就是一个DefaultListableBeanFactory,该类实现了ConfigurableListableBeanFactory接口
getBeanFactoryPostProcessors():
其实就是返回了一个BeanFactoryPostProcessor的List集合,这个集合就是用户自己手动添加的后置处理器
private final List<BeanFactoryPostProcessor> beanFactoryPostProcessors = new ArrayList<>();
.......
return this.beanFactoryPostProcessors;
添加集合的入口
//自定义一个类继承 BFPP
public class ABfpp implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("A的postProcessBeanFactory");
}
}
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
applicationContext.addBeanFactoryPostProcessor(new ABfpp());
applicationContext.refresh();
}
}
可以看到这边已经有了我们刚才添加的ABfpp。
接着就进到invokeBeanFactoryPostProcessors方法,
// Invoke BeanDefinitionRegistryPostProcessors first, if any.
储存已经完成处理的BeanDefinitionRegistryPostProcessor名字
Set<String> processedBeans new HashSet<>();
if (beanFactory instanceof BeanDefinitionRegistry registry) {
//...........
}else{
// Invoke factory processors registered with the context instance.
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
- 可以看到是一个if-else的判断,也就是判断当前使用的工厂是不是
BeanDefinitionRegistry
类型或者其子类,通过uml类图可以发现,当前传入的beanFactory(DefaultListableBeanFactory),是实现了BeanDefinitionRegistry接口
(这个判断99%都会返回为true,为什么呢?因为除非进行了很深度的扩展Spring,自己继承整个工厂的顶级接口AliasRegistry
去实现一个完全由自己实现的工厂,这个判断才会被跳过!这个对于我们现阶段来说,不用太过深究,我们现在就先认定一件事,我们使用的beanFactory工厂一定是 BeanDefinitionRegistry
类型的,这个判断也一定会进来)
- 初始化了2个集合,用于存放
BeanFactoryPostProcessor
和BeanDefinitionRegistryPostProcessor
,其中regularPostProcessors
是用来存放我们手动添加进来的BeanFactoryPostProcessor
,而registryProcessors
是用来存放整个执行过程中找到的BeanDefinitionRegistryPostProcessor
// 用于存放普通的BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
// 存放直接实现BeanDefinitionRegistryPostProcessor,处理过的实现类
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
//目前beanFactoryPostProcessors为空
//调用AbstractApplicationContext.addBeanFactoryPostProcessor设置进去的
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor registryProcessor) {
// 2.1 如果是BeanDefinitionRegistryPostProcessor
// 2.1.1 直接执行BeanDefinitionRegistryPostProcessor接口的postProcessBeanDefinitionRegistry方法
registryProcessor.postProcessBeanDefinitionRegistry(registry);
// 2.1.2 添加到registryProcessors(用于最后执行postProcessBeanFactory方法)
registryProcessors.add(registryProcessor);
}
else {
// 2.2 否则,只是普通的BeanFactoryPostProcessor
// 2.2.1 添加到regularPostProcessors(用于最后执行postProcessBeanFactory方法)
regularPostProcessors.add(postProcessor);
}
}
至此,我们自己手动添加的BeanFactoryPostProcessor
已经添加到集合。接下来根据英文注释可以知道,大概的流程就是将PriorityOrdered
、Ordered
和其余部分的 BeanDefinitionRegistryPostProcessor
分开,按照顺序初始话执行。(PriorityOrdered是一个排序的接口,它的父类是Ordered,谁的值越小越先调用,先简单了解下即可)
// Separate between BeanDefinitionRegistryPostProcessors that implement
// PriorityOrdered, Ordered, and the rest.
// 将实现 PriorityOrdered、Ordered 和其余部分的 BeanDefinitionRegistryPostProcessor 分开。
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
//先执行实现了PriorityOrdered 接口的 BeanDefinitionRegistryPostProcessors
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
//是否实现了PriorityOrdered 接口的
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
//实例化bean
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
//
processedBeans.add(ppName);
}
}
//调用排序方法
sortPostProcessors(currentRegistryProcessors, beanFactory);
//把当前已经处理过的BeanDefinitionRegistryPostProcessor存放到List
registryProcessors.addAll(currentRegistryProcessors);
//执行postProcessBeanDefinitionRegistry方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
//清空currentRegistryProcessors这个集合 在下面的代码复用
currentRegistryProcessors.clear();
-
先初始了
currentRegistryProcessors
,用来存放当前需要执行的BeanDefinitionRegistryPostProcessor
,这个集合会在接下来的代码复用。接着就是getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false)
这个方法,根据名称就知道根据Type获取BeanName,返回一个names的String数组,传入的类型是BeanDefinitionRegistryPostProcessor
(getBeanNamesForType这个方法后面会再详细介绍)。接着遍历这个postProcessorNames,判断这个传入PostProcessorName的BenaDefinition是否符合PriorityOrdered.class,当然该方法的作用不止于此,我们现在只分析有关的。 -
主要重点在
beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)
方法,简单理解为从Spring的容器中获取类,如果不存在则从BeanDefinitionMap中找到对应BeanDefinition,然后实例化返回。(getBean方法会在后面的文章讲解)。可以看到,目前spring内置的实现了PriorityOrdered.class接口的类有ConfigurationClassPostProcessor,这个类很重要。然后将这个ppName存到processedBeans集合中,processedBeans集合就是用来存放已经处理过的BeanDefinitionRegistryPostProcessor或者BeanFactoryPostProcessor的名字,为了后面不重复处理。
-
接下来就是根据order的值大小来排序,当前只有一个ConfigurationClassPostProcessor类,所以这个方法会直接返回return结束。
-
registryProcessors.addAll(currentRegistryProcessors)
这个registryProcessors集合可以理解为用来存放已经执行过postProcessBeanDefinitionRegistry
方法的BeanDefinitionRegistryPostProcessor,下面的代码还要去执行这个它的postProcessBeanFactory
方法。 -
接着就是执行调用invokeBeanDefinitionRegistryPostProcessors方法,执行具体类的postProcessBeanDefinitionRegistry方法。当前spring内置的ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry是个很重要的实现,主要有:解析加了@Configuration的配置类 、解析@ComponentScan扫描的包 、解析@ComponentScans扫描的包、解析@Import注解,这里暂时不往下研究。
-
执行完后清空currentRegistryProcessors这个集合 在下面的代码复用
-
至此,实现了PriorityOrdered.class的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法已经执行完毕,接下来就是实现了Ordered.class的BeanDefinitionRegistryPostProcessor,代码大致和上面的一样,唯一不同的是增加了
!processedBeans.contains(ppName)
判断。上面说过,processedBeans是用来防止重复执行的。if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) { currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); }
-
接下来就是在while循环中,去执行没有实现Order和PriorityOrdered 接口的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法。
看到这里,你可能会有几个疑惑,这里为什么要去while循环呢,为什么getBeanNamesForType被调用了这么多次呢(有4次调用,有3次是针对 BeanDefinitionRegistryPostProcessor 执行的,而仅有一次是针对 BeanFactoryPostProcessor 执行的。)
查阅资料发现,官网的建议是BeanDefinitionRegistryPostProcessor用来添加额外的bd,而BeanFactoryPostProcessor用来修改bd,Spring允许BeanFactoryPostProcessor在容器实例化任何其它Bean之前读取配置元数据,并可以根据需要进行修改。
所以,在BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法调用过程中,可能会影响 Bean 的数量,可能会添加一些的 其他Bean 实例进来,所以需要循环去再次获取,直到没有新的 Bean 实例添加为止。也是为什么要多次调用getBeanNamesForType的原因
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, beanFactory.getApplicationStartup()); currentRegistryProcessors.clear(); }
11.最后就是执行postProcessBeanFactory的方法。先执行registryProcessors集合里BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法,在执行regularPostProcessors集合里BeanFactoryPostProcessor的的postProcessBeanFactory方法。
regularPostProcessors在这个方法中只有在遍历我们手动添加的beanFactoryPostProcessors的时候才有对集合的操作。
// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
到此,BeanDefinitionRegistryPostProcessor的逻辑都处理完了,下面逻辑和处理BeanDefinitionRegistryPostProcessor逻辑一样,只不过是单单处理BeanFactoryPostProcessor的bean。
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
}
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);
}
}
// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// Finally, invoke all other BeanFactoryPostProcessors.
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
// Clear cached merged bean definitions since the post-processors might have
// modified the original metadata, e.g. replacing placeholders in values...
beanFactory.clearMetadataCache();
invokeBeanFactoryPostProcessors整体的流程就是这样,文章中涉及的其他比较重要的如getBean()方法,ConfigurationClassPostProcessor类如何完成扫描的,以及getBeanNamesForType(…)方法,后续会再继续深入研究,新手上路,如有错误的地方还望帮忙指出!及时修改!