一、前文回顾
spring ioc容器创建过程(1)BeanFactory的创建 spring ioc容器创建过程(2)invokeBeanFactoryPostProcessors
二、BeanPostProcessor
BeanPostProcessor 提供Spring Bean 初始化前和初始化后的生命周期回调,分别对应postProcessBeforeInitialization 以及 postProcessAfterInitialization 方法,允许对关心的Bean 进行扩展 ,甚至是替换。 举个例子:
- ApplicationContext 相关的Aware 回调也是基于 BeanPostProcessor 实现,即ApplicationContextAwareProcessor;
- BeanFactoryPostProcessor 是Spring BeanFactory(实际为 ConfigurableListableBeanFactory)的后置处理器,用于扩展 BeanFactory,或通过BeanFactory 进行依赖查找和依赖注入。
但是值得注意的是BeanFactoryPostProcessor 必须要有Spring ApplicationContext 的创建,BeanFactory 无法与其直接进行交互。 而BeanPostProcessor 则直接与BeanFactory 关联,属于N 对1 的关系。
三、BeanFactory注册BeanPostProcessor阶段
3.1、AbstractApplicationContext#registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory)
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
} else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
} else {
nonOrderedPostProcessorNames.add(ppName);
}
}
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
sortPostProcessors(orderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
总体来说就是获取到了BeanFactory中定义的所有的BeanPostProcessor对象,并添加到AbstractBeanFactory中的beanPostProcessors数组中,以便后面创建bean的时候进行调用/
结合上一篇文章的描述,可以发现BeanPostProcessor 的处理与BeanFactoryPostProcessor 的处理极为相似,但是似乎又有些不一样的地方。经过反复的对比发现,对于BeanFactoryPostProcessor的处理要区分两种情况, 一种方式是通过硬编码方式的处理, 另一种是通过配置文件方式的处理。那么为什么在BeanPostProcessor 的处理中只考虑了配置文件的方式而不考虑硬编码的方式呢?对于BeanFactoryPostProcessor的处理,不但要实现注册功能,而且还要实现对后处理器的激活操作,所以需要载入配置中的定义,并进行激活;而对于BeanPostProcessor 并不需要马上调用,再说,硬编码的方式实现的功能是将后处理器提取并调用,这里并不需要调用,当然不需要考虑硬编码的方式了,这里的功能只需要将配置文件的BeanPostProcessor 提取出来并注册进入beanFactory 就可以了。对于beanFactory 的注册,也不是直接注册就可以的。在Spring 中支持对于BeanPostProcessor的排序, 比如根据PriorityOrdered 进行排序、根据Ordered 进行排序或者无序,而Spring 在BeanPostProcessor 的激活顺序的时候也会考虑对于顺序的问题而先进行排序。
3.2、registerBeanPostProcessors
private static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {
Iterator var2 = postProcessors.iterator();
while(var2.hasNext()) {
BeanPostProcessor postProcessor = (BeanPostProcessor)var2.next();
beanFactory.addBeanPostProcessor(postProcessor);
}
}
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
this.beanPostProcessors.remove(beanPostProcessor);
this.beanPostProcessors.add(beanPostProcessor);
if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
this.hasInstantiationAwareBeanPostProcessors = true;
}
if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
this.hasDestructionAwareBeanPostProcessors = true;
}
}
在registerBeanPostProcessors 方法的实现中确保了beanPostProcessor的唯一性,个人猜想,之所以选择在registerBeanPostProcessors 中没有进行重复移除操作或许是为了保持分类的效果,使逻辑更为清晰吧。
四、总结
AbstractApplicationContext#registerBeanPostProcessors(ConfigurableListableBeanFactory) 方法,主要初始化 BeanPostProcessor 类型的 Bean(依赖查找),会做以下事情:
- 获取所有 BeanPostProcessor 类型的 beanName
- 添加 BeanPostProcessor - BeanPostProcessorChecker,用于打印日志(所有 BeanPostProcessor 还没有全部实例化就有 Bean 初始化完成)
- 获取所有 BeanPostProcessor 实现类(依赖查找),添加至 BeanFactory 容器中(顺序:PriorityOrdered > Ordered > 无)
- 注意,第
3 步添加的 BeanPostProcessor 如果是 MergedBeanDefinitionPostProcessor 类型,会再次添加(先移除在添加,也就是将顺序往后挪) - 重新添加 BeanPostProcessor - ApplicationListenerDetector,目的将其移至最后,因为这个后置处理器用于探测 ApplicationListener 类型的 Bean,需要保证 Bean 完全初始化,放置最后比较合适。
|