后置处理器是Spring框架提供的对外扩展点,通过实现对应接口,可以对bean进行各种操作(bean定义bd进行修改或者对初始化前后的bean进行各种修改),其中之一是BeanPostProcessor,本文主要从源码角度了解BeanPostProcessor的原理和执行过程。
BeanPostProcessor作为Spring框架重要的扩展点,对外提供了对bean实例化后,操作的空间,主要是涉及到对bean执行初始化方法前后调用对应方法实现对bean的各种功能增强,比如spring aop是利用BeanPostProcessor实现的代理增强。
BeanPostProcessor的主要分析应该包括两部分:
以AnnotationConfigApplicationContext为例,对BeanPostProcessor的注册在AbstractApplicationContext.refresh方法
该方法最终调用的是下面方法进行的核心处理
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this)
主要逻辑完成三件事
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
// Register BeanPostProcessorChecker that logs an info message when
// a bean is created during BeanPostProcessor instantiation, i.e. when
// a bean is not eligible for getting processed by all BeanPostProcessors.
/**
* 目标总数:获取已经实例化的BeanPostProcessor+ 1(BeanPostProcessorChecker) + 已经注册的bd但是还未实例化
* BeanPostProcessorChecker作用:
* 在所有BeanPostProcessor实例化期间,如果有bean创建,则打印日志记录-该bean的初始化可能不能得到所有后置处理器的处理,
* 以为还有已经注册bd,但是未实例化的bd
*/
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
通过BeanPostProcessorChecker判断BeanPostProcessor注册期间是否有注册新的bean,检测逻辑如下图
通过this.beanFactory.getBeanPostProcessorCount() < this.beanPostProcessorTargetCount,判断是否已经完成所有BeanPostProcessor的注册
该过程就是根据BeanPostProcessor实现的各种接口判断优先级,逻辑比较简单:
/**
* 将后置处理器按照以下四类进行排序添加
* 1. 实现PriorityOrdered接口
* 2. 实现Ordered接口
* 3. 实现MergedBeanDefinitionPostProcessor,内部后置处理器
* 4. 其它后置处理器
* 对上述的处理分别按照类别进行排序,然后添加到beanPostProcessors缓存中
*/
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)) {
//getBean--实例化,初始化bd
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);
}
}
// First, register the BeanPostProcessors that implement PriorityOrdered.
//排序
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
//实例化注册
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// Next, register the BeanPostProcessors that implement Ordered.
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);
// Now, register all regular BeanPostProcessors.
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);
// Finally, re-register all internal BeanPostProcessors.
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
将后置处理器按照以下四类进行排序添加
1. 实现PriorityOrdered接口
2. 实现Ordered接口
3. 实现MergedBeanDefinitionPostProcessor,内部后置处理器
4. 其它后置处理器
对上述的处理分别按照类别进行排序,然后添加到beanPostProcessors缓存中
注册逻辑如下,主要是根据bean工厂类型,有一个批量添加(底层CopyOnWriteArrayList复制加锁批量添加)的区别
由于在prepareBeanFactory时已经添加了ApplicationListenerDetector,这里之所以要重新添加是为了能够处理代理bean,主要代码就一句如下图
官方注释意思应该是拾取代理,从而放最后一个进行注册,对代理bean也能够进行处理,避免先执行而无法获取代理bean。
在创建bean,执行bean初始化前后执行具体是doCreateBean–>initializeBean这个方法
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 处理初始化前执行postProcessBeforeInitialization
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
//初始化
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
//处理初始化后执行postProcessAfterInitialization
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
在执行初始化bean前后调用,调用函数如下就是根据添加顺序依次处理,这也是为什么需要把ApplicationListenerDetector放到末尾处理,以防止较早处理获取不到代理对象。
首先自定义一个实现BeanPostProcessor的类和待处理的类
本篇文章主要是对BeanPostProcessor作用、注册和执行时机源码进行了学习,并对如何使用BeanPostProcessor扩展做了一个测试。