invokeBeanFactoryPostProcessors执行流程解析

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);
}
  1. 可以看到是一个if-else的判断,也就是判断当前使用的工厂是不是BeanDefinitionRegistry类型或者其子类,通过uml类图可以发现,当前传入的beanFactory(DefaultListableBeanFactory),是实现了BeanDefinitionRegistry接口

(这个判断99%都会返回为true,为什么呢?因为除非进行了很深度的扩展Spring,自己继承整个工厂的顶级接口AliasRegistry去实现一个完全由自己实现的工厂,这个判断才会被跳过!这个对于我们现阶段来说,不用太过深究,我们现在就先认定一件事,我们使用的beanFactory工厂一定是 BeanDefinitionRegistry类型的,这个判断也一定会进来)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KI4zuEn7-1669792531281)(/Users/ys7/Library/Application Support/typora-user-images/image-20221115165648042.png)]

  1. 初始化了2个集合,用于存放BeanFactoryPostProcessorBeanDefinitionRegistryPostProcessor,其中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已经添加到集合。接下来根据英文注释可以知道,大概的流程就是将PriorityOrderedOrdered 和其余部分的 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();
  1. 先初始了currentRegistryProcessors,用来存放当前需要执行的BeanDefinitionRegistryPostProcessor,这个集合会在接下来的代码复用。接着就是getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false)这个方法,根据名称就知道根据Type获取BeanName,返回一个names的String数组,传入的类型是BeanDefinitionRegistryPostProcessor(getBeanNamesForType这个方法后面会再详细介绍)。接着遍历这个postProcessorNames,判断这个传入PostProcessorName的BenaDefinition是否符合PriorityOrdered.class,当然该方法的作用不止于此,我们现在只分析有关的。

  2. 主要重点在beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)方法,简单理解为从Spring的容器中获取类,如果不存在则从BeanDefinitionMap中找到对应BeanDefinition,然后实例化返回。(getBean方法会在后面的文章讲解)。

    可以看到,目前spring内置的实现了PriorityOrdered.class接口的类有ConfigurationClassPostProcessor,这个类很重要。然后将这个ppName存到processedBeans集合中,processedBeans集合就是用来存放已经处理过的BeanDefinitionRegistryPostProcessor或者BeanFactoryPostProcessor的名字,为了后面不重复处理。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-e7kuqZy2-1669792531281)(/Users/ys7/Library/Application Support/typora-user-images/image-20221129171223455.png)]

  3. 接下来就是根据order的值大小来排序,当前只有一个ConfigurationClassPostProcessor类,所以这个方法会直接返回return结束。

在这里插入图片描述

  1. registryProcessors.addAll(currentRegistryProcessors)这个registryProcessors集合可以理解为用来存放已经执行过postProcessBeanDefinitionRegistry方法的BeanDefinitionRegistryPostProcessor,下面的代码还要去执行这个它的postProcessBeanFactory方法。

  2. 接着就是执行调用invokeBeanDefinitionRegistryPostProcessors方法,执行具体类的postProcessBeanDefinitionRegistry方法。当前spring内置的ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry是个很重要的实现,主要有:解析加了@Configuration的配置类 、解析@ComponentScan扫描的包 、解析@ComponentScans扫描的包、解析@Import注解,这里暂时不往下研究。

  3. 执行完后清空currentRegistryProcessors这个集合 在下面的代码复用

  4. 至此,实现了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);
    }
    
  5. 接下来就是在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(…)方法,后续会再继续深入研究,新手上路,如有错误的地方还望帮忙指出!及时修改!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值