上一篇,我们看到ApplicationContext对BeanFactory一些扩展的功能点,包括对SPEL语言的支持、添加属性编辑器的注册等。下面我们继续分析ApplicationContext对初级容器BeanFactory的一些其他的功能扩展点。我们接着之前的refresh方法接下分析。
我们从方法postProcessBeanFactory开始分析,进入到方法postProcessBeanFactory中看下:
可以看到方法postProcessBeanFactory是一个空实现,该方法也是被protected修饰了。说明这个也是spring提供给我们的一个扩展点。那方法postProcessBeanFactory留给子类具体要去实现什么样的功能呢?通过这个注释我们知道是spring暴露给子类去修改容器beanFactory的。那子类什么时候可以修改beanFactory呢?从注释中我们可以看出,是所有bean的BeanDefinition都注册到了BeanFactory中,但是还没有进行实例化的时候进行修改,这个是什么意思呢?我们之前将spring从xml中解析bean的标签,然后将解析到的BeanDefinition注入到spring容器中,这些都是bean属性信息的一个初始化。而bean的实例化就是创建Java对象,spring就会获取容器中的BeanDefinition中的各种属性和值去创建一个bean出来,这个过程就是bean的实例化。所以,相当于方法postProcessBeanFactory给了我们一个机会,在实例化之前bean之前修改bean的一下属性信息,我们根据方法postProcessBeanFactory的参数beanFactory,就可以获取到所有注册的bean的消信息了。
我们写一个案例测试一下:
我们重写了postProcessBeanFactory方法,我们通过student 名称获取到了bean的定义信息,然后我们把student类型修改为了BeanDefinition.SCOPE_PROTOTYPE。然后测试验证一下:
可以看到结果都是一样的:
当然,我们在postProcessBeanFactory中可以获取到beanFactory,我们可以做的事情当然也不仅仅只是局限于修改BeanDefinition的信息了,而是整个beanFactory级别的信息都可以修改了。
接下来,我们继续往后看:
接着就开始调用方法invokeBeanFactoryPostProcessors,我们到方法中看下:
通过注册我们知道是要实例化并且调用所有的BeanFactoryPostProcessor,那什么是BeanFactoryPostProcessor呢?我们都方法BeanFactoryPostProcessor中看下:
可以看到,BeaFactoryPostProcessor中的方法和我们刚才看到的空实现方法postProcessBeanFactory几乎是一模一样,目的也是一样的,就是允许我们通过beanFactory去获取相应的BeanDefinition并修改相应的信息。
我们通过案例演示一下:
把自定义的BeaFactoryPostProcessor 添加到xml文件中:
测试:
结果:
既然postProcessBeanFactory 空方法已经可以修改beanFactory容器信息,为什么 spring还给我们提供接口BeanFactoryPostPorcessor呢?因为我之前通过postProcessBeanFactory 毕竟是需要继承容器来实现的,这种耦合性还是比较强,但是有了BeanFactoryPostProcessor接口之后,我们可以为每种修改操作分别创建一个类来实现接口BenaFactoryPostProcessor,这样的话至少在代码上实现了解耦的。
我们回到之前的代码:
我们到方法invokeBeanFactoryPostProcessors中看下:
可以看到,首先会通过方法getBeanFactoryPostProcessors获取参数中的工厂后处理器BeanFactoryPostProcessor,然后调用方法invokeBeanFactoryPostProcessors执行工厂后处理器中的方法。
我们跟进到invokeBeanFactoryPostProcessors方法中看下:
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// Invoke BeanDefinitionRegistryPostProcessors first, if any.
Set<String> processedBeans = new HashSet<>();
// 1、判断BeanFactory是否为BeanDefinitionRegistry接口的实现类
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
// 1.1 存放普通的BeanFactoryProcessor
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
// 1.2 存放BeanDefinitionRegistryPostProcessor类型的BeanFactoryPostProcessor
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
// 1.3 遍历参数中的beanFactoryPostProcessors(默认为空实现)
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
// 判断postProcessor是普通工厂后处理器,还是BeanDefinitionRegistryPostProcessor类型的
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
// 1.3.1 首先执行BeanDefinitionRegistryPostProcessor中的方法postProcessBeanDefinitionRegistry
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
//1.3.2 然后在将registryProcessor存储起来(方便后续执行方法postProcessBeanFactory)
registryProcessors.add(registryProcessor);
}
else {
// 如果是普通的工厂后置处理器,那就是实现以借口BeanFactoryPostProcessor,然后在存放到普通工厂处理器集合中
regularPostProcessors.add(postProcessor);
}
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
// Separate between BeanDefinitionRegistryPostProcessors that implement
// PriorityOrdered, Ordered, and the rest.
// 1.4 利用保存当前需要执行的BeanDefinitionRegistryPostProcessor(每处理完一批,就会清空)
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
// 1.5 处理beanFactory中,既已经实现BeanDefinitionRegistryPostProcessor 又实现接口 PriorityOrdered的实现类
// 从beanFactory中,获取类型为BeanDefinitionRegistryPostProcessor的所有的bean
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
//找到这些实现了接口BeanDefinitionRegistryPostProcessor类,同时实现了接口PriorityOrdered的实现类
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
// 添加到当前处理的BeanDefinitionRegistryPostProcessor集合中
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
// 记录类型为BeanDefinitionRegistryPostProcessor的bean名称(避免后续相同的bean重复执行了)
processedBeans.add(ppName);
}
}
// 根据PriorityOrdered后置ordered接口解析排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
// 添加到registryProcessors集合中(方便后续执行方法postProcessorBeanFactory)
registryProcessors.addAll(currentRegistryProcessors);
// 执行currentRegistryProcessors中,第一阶段方法postProcessBeanDefinitionRegistry
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
// 执行完成之后 清空
currentRegistryProcessors.clear();
// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
// 1.6 处理beanFactory中既实现了接口BeanDefinitionRegistryPostProcessor,又实现了Ordered的实现类 (大概的流程和1.5 类似)
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();
// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
// 1.7 处理beanFactory中实现接口BeanDefinitionRegistryPostProcessor的实现类,同时这些实现类不能包含前面已经处理的
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
// 处理完所有的postProcessorNames,然后reiterate 变为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();
}
// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
// 1.8 统一调用BeanDefinitionRegistryPostProcessor类型工厂后处理器的postProcessorBeanFactory方法
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
// 1.9 统一调用普通类型工厂后处理器的postProcessorBeanFactory方法
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
else {
// Invoke factory processors registered with the context instance.
// 如果beanFactory不是BeanDefinitionRegistry的实现类,就是我们的普通工厂后置处理器,直接调用postProcessorBeanFactory方法了
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
// 上面参数beanFactoryPostProcessors以及容器beanFactory中所有类型为BeanDefinitionRegistryPostProcessor的bean全部处理完了
// 接下来处理beanFactory中纯粹实现BeanFactoryPostProcessor接口实现类
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
// 存放实现接口PriorityOrdered接口的BeanFactoryPostProcessor接口实现类名称
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
// 存放实现接口ordered接口的BeanFactoryPostProcessor接口实现类名称
List<String> orderedPostProcessorNames = new ArrayList<>();
// 存放无序的BeanFactoryPostProcessor接口实现类名称
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.
// 根据PriorityOrdered排序
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
// 执行工厂的后置处理器
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
// 根据刚才记录的Ordered接口的bean名称,从beanFactory中获取对应的bean,然后根据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.
// 根据记录的无序的bean的名称,从beanFactory中获取对应的bean,然后执行工厂后置处理器
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方法的逻辑看起来很复杂,但是我们一步一步的分析,会发现里面的重复代码也是比较多的。
我们接下来,开始慢慢的分析:
首先先判断beanFactory是否实现类BeanDefinitionRegistery的实现类。我先回顾下我们执行DefaultListableBeanFactory 的类继承图:
DefaultListableBeanFactory实现了BeanDefinitionRegistry的,所以第一个方法是会进入的。我们看下刚才的代码
在这个分支中,分别用来存放BeanFactoryPostProcessor集合regularPostProcessors以及存放BeanDefinitionRegistryPostProcessor集合registryProcessors。在上面的篇符中我们介绍了BeanFactoryPostProcessor。那这个BeanDefinitionRegistryPostProcessor又是什么呢?
我们来看一张类图来了解下:
可以看到BeanDefinitionRegistryPostProcessor只是继承了BeanFactoryPostProcessor的接口而已。它里面有一个方法postProcessBeanDefinitionRegistry,并且参数是BeanDefinitionRegistry。从上面这个图片可以看出BeanDefinitionReistry中定义了一系列和BeanDefinition相关的方法,包括对BeanDefinition的注册、查看、或者删除操作,而且通过类名我们可以知道BeanDefinitionRegistry的postProcessBeanDefinitionRegistry方法,一般是用来注册新的BeanDefinition的。从这里我们也可以看出来,spring容器中的BeanDefinition并不一定是要从xml中解析得来,我们也可以自定义BeanDefinition,通过
BeanDefinitionRegistryPostProcessor的接口方法postProcessBeanDefinitionRegistry注入到spring容器中。
了解完postProcessBeanDefinitionRegistry和 postProcessBeanFactory区别之后,我们继续分析刚才的代码:
初始化完两个集合之后,就是将BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor分别存放到相应的集合中。但是存放BeanDefinitionRegistryPostProcessor的实现类到集合之前,会预先执行接口中的方法postProcessBeanDefinitionRegistry,将BeanDefinition先注册到Spring容器中。父类中的方法postProcessorBeanFactory留到后面统一在处理。
我们看下一部分代码:
可以看到,首先会创建currentRegistryProcessors集合用于存放BeanDefinitionRegistryPostProcessor,这个是个临时的集合,每处理完一批数据会清空一批。接着我们就会通过beanFactory获取spring容器中所有BeanDefinitionRegistryPostProcessor类型的bean名称,然后存放到postProcessorNames数组中。可以看到优先处理的是实现接口BeanDefinitionRegistryPostProcessor的类。然后通过for循环遍历筛选出实现BeanDefinitionRegistryPostProcessor接口同时实现了PriorityOrdered接口的类,并将这些类都存放到集合currentRegistryProcessors中准备处理它。
继续往下看:
接下来会调用sortPostProcessors对currentRegistryProcessors集合进行排序,我们知道当前获取到的这些类是实现了接口PriorityOrdered。这个PriorityOrdered 是什么呢?我们看下这个PriorityOrdered继承类图:
可以看到接口PriorityOrdered里面什么也没有,只是继承了接口Ordered,并且接口Ordered中只有一个方法getOrder,那Spring为什么要设计这两个接口出来呢?我们从PriorityOrdered和Ordered的类名称也能看出一点,那就是顺序和优先级,也就是说在Spring中有大量的类都实现了接口BeanDefinitionRegistryPostProcessor,那么在执行的时候肯定就会存在优先级也就是哪个先执行哪个后执行的问题。默认情况下,实现接口PriorityOrdered的优先级比实现了接口Ordered的优先级高,如果同时实现PriorityOrdered接口或Ordered接口,那就看getOrder方法返回的结果哪个值更小,值更小的那个实现类优先级更高。
我们看下刚才的代码:
可以看到,接下来就是调用方法sortPostProcessors对集合currentRegistryProcessors进行排序,集合currentRegistryProcessors中的这些类都是实现接口PriorityOrdered的,所以会根据getOrder方法的返回值进行排序,值越小优先级越大。然后,将集合currentRegistryProcessors中的数据,像我们刚才处理参数beanFactoryPostProcessors一样存放到集合registryProcessors中,方便后续统一执行剩下的方法postProcessBeanFactory。实现了接口PriorityOrdered的BeanDefinitionRegistryPostProcessor都已经处理完了,会清空集合currentRegistryProcessors并准备处理下一批数据。
我们继续看下一阶段的代码:
刚才我们已经处理beanFactory中实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor。现在,我们可以看到接下来的代码逻辑基本和我们前面分析的一样,只不过,现在处理的并不是实现接口PriorityOrdered的BeanDefinitionRegistryPostProcessor了,而是处理实现了接口Ordered的BeanDefinitionRegistryPostProcessor。如果实现了接口PriorityOrdered和Ordered的BeanDefinitionRegistryPostProcessor都处理完了,那最后应该处理的就是没有实现PriorityOrdered和Ordered的BeanDefinitionRegistryPostProcessor了,我们来看下会如何处理:
可以看到,在while循环当中不断的从beanFactory获取接口BeanDefinitionRegistryPostProcessor的实现类,并且之前处理过的类,都会通过代码 processedBeans.contains(ppName) 排除掉。也就是剔除掉实现接口PriorityOrdered和Ordered的BeanDefinitionRegistryPostProcessor,剩下的就是处理没有实现这两个接口的,也就是普通的无序的BeanDefinitionRegistryPostProcessor了。我们在看下面的代码:
可以看到,之前在集合registryProcessors及regularPostProcessors记录的BeanFactoryPostProcessor,此时都分别在方法invokeBeanFactoryPostProcessors中,统一调用方法postProcessBeanFactory来修改BeanDefinition。
我们现在总结一下上面方法执行的流程:
1、首先处理参数中的beanFactoryPostProcessors按两种类型处理,分别是实现了接口BeanDefinitionRegistryPostProcessor的BeanFactoryPostProcessor,以及没实现该接口普通BeanFactoryPostProcessor,它们分别存放在集合registryProcessors和regularPostProcessors中。
2、如果实现了接口BeanDefinitionRegistryPostProcessor,率先会调用BeanDefinitionRegistryPostProcessor中的方法postProcessBeanDefinitionRegistry来注册一些BeanDefinition。
3、参数中的beanFactoryPostProcessors处理完毕之后,接着处理容器beanFactory中的BeanFactoryPostProcessor,优先从容器beanFactory中获取实现了接口BeanDefinitionRegistryPostProcessor的类,并且按照以下三种类型来处理:分别是实现了接口PriorityOrdered、Ordered以及这两个接口都没有实现的无序的普通类,和前面一样这三种类型的类都是实现了接口BeanDefinitionRegistryPostProcessor的,优先执行BeanDefinitionRegistryPostProcessor中的方法postProcessBeanDefinitionRegistry,来注册一些自定义的BeanDefinition。
4、最后会统一执行BeanDefinitionRegistryPostProcessor的父类,以及普通BeanFactoryPostProcessor类中的方法postProcessBeanFactory,完成一些自定义的修改BeanDefinition操作。
上面的步骤是已经处理完BeanDefinitionRegistryPostProcessor,接下来最后一部分就是开始处理BeanFactoryPostProcessor的类,我们一起看下这个代码:
按照我们刚说的三种类型,实现priorityOrdered接口、实现Ordered接口和两个接口都没有实现的情况,分别从容器beanFactory获取相应的BeanFactoryPostProcessor实现类。并且我们可以看到首先处理实现接口PriorityOrdered的BeanFactoryPostProcessor实现类,所以说PriorityOrdered优先级是最高的。
我们继续往下看:
接下来开始处理剩下的两种类BeanFactoryPostProcessor。并且在处理到最后会清理BeanFactory的元数据缓存。
可以看到在这个环节主要是处理BeanFactory中实现接口BeanFactoryPostProcessor的实现类和实现接口BeanDefinitionRegistryPostProcessor实现类。它们会按照三种类型来处理,分别是实现了PriorityOrdered接口、Ordered接口以及这两种接口都没有实现的普通类,也就是没有顺序的。
我们总结一下我们今天将的内容: