spring源码-refresh中的postProcessBeanFactory方法和invokeBeanFactoryPostProcessors方法
refresh中的postProcessBeanFactory方法

点进去看看这个方法

这是一个模板方法模式,由可以由子类来实现
在看下一个方法前,我们需要做一些准备,我们要知道invokeBeanFactoryPostProcessors它是会去调用,我们在prepareBeanFactory中的两个postProcessor,不信我们debug一下
我们能够看到invokeBeanFactoryPostProcessor对beanPostProcessor的方法做了执行,这是一个容易被忽略的一个点,因为这个方法叫invokeBeanFactoryPostProcessor,它不仅会执行beanFactoryPostProcessor的方法还会执行beanPostProcessor的方法

我们可以通过继承这个接口来达到一个修改bean的一个功能
同时呢,我们还有beanFactoryPostProcessor

它的话有一个子类和他本身可以去做到对beanFactoryPostProcessor的方法执行

BeanPostProcessor的优先级低,而BeanDefinitionRegistryPostProcessor的优先级高
继续看下一个方法

进入看看

首先看第一个方法,很长,慢慢看

我们分块解析,先看第一块是在干什么

processedBeans一但我们有执行过的Bean就放进去,防止重复执行
我们传入的beanFactroy做一个是否是BeanDefinitionRegistry的判断
我们列一下调用链首先beanFactory是来自于obtainFreshBeanFactory,那么obtainFreshBeanFactory中呢它返回的是getBeanFactory的抽象方法,那我们都知道抽象方法要找到它的子类实现来执行,那么它的子类实现应该是genericApplicationContext的getBeanFactory方法,这个方法会返回它一开始就初始化的DefaultListableBeanFactory,那么这个类它是继承自BeanDefinitionRegistry,所以这里的判断是一定会进入的
紧接着我们来看,他将DefaultListableBeanFactory强转成BeanDefinitionRegistry,然后new了两个数组,一个BeanFactoryPostProcessor类型的,一个BeanDefinitionRegistyPostProcessor这两个是不是前面那说的,beanFactoryPostProcessor优先级低,BeanDefinitionRegistyPostProcessor优先级高,那么我们就能知道这里面存储就是两种不同实现的BeanFactoryPostProcessor,然后它会去遍历传进来的beanFactoryPostProcessors,这个beanFactoryPostProcessors
这个方法返回了this.beanFactoryPostProcessors,我们并没有能够初始化这个beanFactoryPostProcessors,所以长度为0

它没能进去,它里面做的还事情还挺清楚的,如果是BeanDefinitionRegistyPostProcessor类型的,将BeanDefinitionRegistyPostProcessor转换成BeanDefinitionRegistyPostProcessor,执行方法并添加,如果不是就加入到BeanFactoryPostProcessor的List中
接着看

currentRegistryProcessors又来一个,这是干什么用的?其实他就是存储的当前需要执行但是还未进行执行的Bean,我们通过前一篇文章中讲到的getBeanNamesForType根据by type拿到bean

我们可以看到这个类,我们是不是在哪见过这个类,我把调用路径写出来AnnotationConfigApplicationContext->this->new AnnotatedBeanDefinitionReader->this->AnnotatedBeanDefinitionReader->registerAnnotationConfigProcessors找到
这里是spring的几个核心bean的注册,详情可以会去看第一篇文章,总之ConfigurationClassPostProcessor继承自BeanDefinitionRegistryPostProcessor,那么就去遍历
遍历进来判断是否匹配PriorityOrdered,PriorityOrderd有什么用?在BeanDefinitionRegistryPostProcessor中,priorityOrderd优先级>Orderd优先级>什么都没有的优先级
然后这个里面的getBean我们先不说,这是另一个分支的,他这内部就是将这个bean加入当前要执行但还未执行的List中,反正也快执行了,顺便加入到已执行的List中
接着看下一小块代码

这里使用了sortPostProcessor,排序,加入我们不止一个postProcessor使用了priorityOrdered呢?那我们就需要进行排序,进入查看方法

如果只有一个那么直接返回不排序,如果有多个,那么它会去调用getDependencyComparator,这个也有但熟悉,同样的AnnotationConfigApplicationContext->this->new AnnotatedBeanDefinitionReader->this->AnnotatedBeanDefinitionReader->registerAnnotationConfigProcessors
里面有order和priority

这里我们清楚了,接着往下走
那么这时候我们的优先级高的BeanDefinitionRegistryPostProcessor还空着呢,我们在前面一直找的都是优先级高的BeanDefinitionRegistryPostProcessor,那么如果有的话我们是不是该加入到这个registryProcessor这个List中
前面一直在各种排序赋值,那我这个BeanDefinitionRegistryPostProcessor的方法到底啥时候执行呢?
接下面invokeBeanDefinitionRegistryPostProcessors这个方法就会开始执行
传进来的是一个当前需要执行的BeanDefinitionRegistryPostProcessor的List,那么我们遍历一个个去执行
那么我们执行完了之后得去做一个清空
那么我们再看下一个小块,结构类似
那不就是没执行过的Bean按照order排序再来一遍执行?前面就说过,PriorityOrderd优先级>Orderd优先级执行,这里就体现出来了,第二次还会加载我们自定义的bean
那既不是priorityOrdered和Ordered的呢?再往下看结构还还还是一样
这次就只判断未执行过的Bean了,他一进来就改成false
最后invokeBeanFactoryPostProcessors是这样的,如果你实现的是BeanDefinitionRegistryPostProcessor,那么它的父类BeanFactoryPostProcessor也要实现,也有一个方法,那么这个invokeBeanFactoryPostProcessor就是去调用实现了BeanDefinitionRegistryPostProcessor的类的BeanFactoryPostProcessor的方法的,然后再invokeBeanFactoryPostProcessors执行实现了BeanFactoryPostProcessor的类的方法,但是现在还没加入,所以这里的regularPostProcessor里面应该没有东西
这次它会去扫描BeanFactoryPostProcessor的,在上面扫到两个,那么在这里应该在两个基础上再加一个,然后有一次存放priority的,有一次存放Order的,有一次存放啥也不是的,三个LIst
那么进入循环,第一个判断将两个执行过的提出了,最后剩下一个internalEventListenerProcessor,它啥也不是,那么就会加到non那个LIst里面,紧接着
一样的,对priority的做排序执行,对order的做排序执行,对什么都不是的做排序执行,执行的都是BeanFactoryPostProcessor里的方法,不是BeanDefinitionRegistryPostProcessor里的方法
最后做缓存清除
走进第一个方法

mergedBeanDefinitions说白了就是将我们注册的beanDefinition和自定义的beanDefinition做了融合
他和DefualtListableBeanFactory中的beanDefinitionMap是一样的
为什么要清空缓存,因为我们调用了getBean,getBean里面会调用createBean有新bean的创建,就有可能definition变化的可能,docreateBean它里面会调用beanPostProcessors,那么可能会导致beanDefinition发生变化,那就必须得清空
总结一下这个invokeBeanFactoryPostProcessors就是按照优先级来执行实现了BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor还有getBean中的执行方法,getBean方法源码之后再说

浙公网安备 33010602011771号