上一篇,我们讲完了执行BeanFactoryPostProcessor后置处理器的执行过程,接下我们讲这个BeanPostProcessor注册。我们接着之前的代码:
文章图片
我们到方法registerBeanPostProcessor中看下:
文章图片
该方法又委托PostProcessorRegistrationDelegate中的registerBeanPostProcessors进行注册,不过在分析这个之前,我们先了解一下BeanPostProcessor是什么?BeanPostProcessor它就是在bean的层面对bean实例化的一个扩展,也就是说通过BeanPostProcessor可以控制spring容器中任意一个bean的实例化过程。我们先看下BeanPostProcessor中的方法:
文章图片
在BeanPostProcessor中有两个方法,分别是postProcessorBeforeInitialization和postProcessorAfterInitializaion。通过方法名称我们知道,分别是在实例化前和实例化后会分别执行的后处理方法,我们可以在这两个方法中,分别添加一些代码逻辑,这样当一个bean在实例化开始前和实例化结束后,就可以分别调用这两个方法了,从而介入bean的实例化过程了。
我们来写个案例:
文章图片
添加到xml文件中:
文章图片
测试:
文章图片
结果:
文章图片
和我们预期的一样,在实例化bean的前后,分别执行了方法postProcessorBeforeInitialization和postProcessAfterInitialization,得到了我们想要的结果。
通过spring容器注册的各种BeanPostProcessor,我们可以对任意一个我们想要的bean进行实例的控制,添加我们想要的逻辑。比如,我们实例化一个bean,到底是直接通过关键词new出来,还是通过jdk动态代理或者CGLIB动态代理呢?我们可以在bean的后处理器BeanPostProcessor方法中,决定bean到底该用哪种方式来实例化bean的。了解完BeanPostProcessor之后,我们接着刚才的流程继续看下spring是如何注册BeanPostProcessor的。
文章图片
我们到registerBeanPostProcessors方法中看下:
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {// 1、 获取容器beanFactory中所有实现BeanPostProcessor类型的实现类
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.
//最终容器中的bean后置处理器
// 容器中已经注册的bean后置处理器+ 即将要注册的后处理器BeanPostProcessorChecker + 容器中还没有注册的bean后处理器数量
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
// 2、检查出哪些bean没有资格被所有的bean后置处理器处理,记录相应的日志
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// Separate between BeanPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
// 3、初始化存放BeanPostProcessor集合
// 存放实现了接口PriorityOrdered的bean后处理器BeanPostProcessor
List priorityOrderedPostProcessors = new ArrayList<>();
// 存放spring内部的bean后处理器BeanPostProcessor
List internalPostProcessors = new ArrayList<>();
// 存放实现了接口Ordered的bean后处理器BeanPostProcessor
List orderedPostProcessorNames = new ArrayList<>();
// 存放无序的bean的后处理器BeanPostProcessor
List nonOrderedPostProcessorNames = new ArrayList<>();
// 4、遍历所有后处理器BeanPostProcessor的名称
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
//添加实现了接口PriorityOrdered的bean后处理器名称
priorityOrderedPostProcessors.add(pp);
// 是spring内部的BeanPostProcessor和实例化注解bean关系密切 如@AutoWired
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
// 添加实现接口Ordered的bean后处理器名称
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
// 添加无序的bean后处理器名称
nonOrderedPostProcessorNames.add(ppName);
}
}// First, register the BeanPostProcessors that implement PriorityOrdered.
// 5、对这个实现了PriorityOrdered的bean后处理器进行排序,然后注册到spring容器中
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// Next, register the BeanPostProcessors that implement Ordered.
// 注册实现Ordered接口的BeanPostProcessor
List orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String ppName : orderedPostProcessorNames) {
// 根据名称,从容器中获取相应的bean后处理器BeanPostProcessor
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
// 如果实现接口MergedBeanDefinitionPostProcessor的后处理器,添加到集合internalPostProcessors中
internalPostProcessors.add(pp);
}
}
// 6、对这个实现了Ordered的bean后处理器进行排序,然后注册到spring容器中
sortPostProcessors(orderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// Now, register all regualr BeanPostProcessors.
// 处理无序的BeanPostProcessor并注册的spring容器中
List nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
// 如果实现接口MergedBeanDefinitionPostProcessor的后处理器,添加到集合internalPostProcessors中
internalPostProcessors.add(pp);
}
}
// 7、 将无序普通的bean后处理器 注册的容器beanFactory中
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// Finally, re-register all internal BeanPostProcessors.
// 8、最后将spring容器内部的BeanPostProcessor 注册到bean后处理器尾部
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
// Re-register post-processor for detecting inner beans as ApplicationListeners,
// moving it to the end of the processor chain (for picking up proxies etc).
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
} private static void sortPostProcessors(List> postProcessors, ConfigurableListableBeanFactory beanFactory) {
// Nothing to sort?
if (postProcessors.size() <= 1) {
return;
}
Comparator
比起我们之前看的BeanFactPostProcessor这一块代码要少很多。我们还是一步一步的分析吧:
文章图片
首先从BeanFactory中获取所有接口BeanPostProcessor的实现类名称,然后先往beanFactory中添加了一个bean后处理器BeanPostProcessorChecker。BeanPostProcessorChecker的功能,其实就是简单检测一下哪些bean是没有资格让所有的BeanPostProcessor处理它,并记录一下日志信息而已。
我们继续看:
文章图片
可以看到初始化了好几个集合,我们可以很清晰的知道这些集合中,priorityOrderedPostProcessors是存放实现了接口PriorityOrdered的BeanPostProcessor,orderedPostProcessorNames存放实现了接口Ordered的BeanPostProcessor,而nonOrderedPostProcessorNames则存放无序的普通的。而集合internalPostProcessors比较特殊,是用于存放Spring容器内部,在解析各种注解时临时生成的BeanPostProcessor,比如解析@Autowired注解时就会生成,后续我们分析到注解相关的源码时就可以看到了,这部分的BeanProcessor也是要注册的。
我们继续往下看:
文章图片
首先将实现了PriorityOrdered接口、Ordered接口、以及这两个接口都没实现的普通无序BeanPostProcessor接口实现类,将这三种类型的BeanPostProcessor都放到相应的集合中。其中,如果发现BeanPostProcessor实现类实现了MergedBeanDefinitionPostProcessor,就放到集合internalPostProcessors中,被认定是Spring内部生成的。而且,我们接着看到率先对实现接口PriorityOrdered的实现类进行排序和注册,需要注意一点的是这里只是将BeanPostProcessor注册到Spring容器beanFactory中,而不是像BeanFactoryPostProcessor一样立马就执行方法了,BeanPostProcessor中的方法是在bean实例化的时候执行的。
我们看最后一部分代码:
文章图片
可以看到,接下来就是依次处理剩下几个集合中的BeanPostProcessor,当然,在这个过程当中我们看到还会筛选出Spring容器内部的BeanPostProcessor,并放到集合internalPostProcessors中。最终,internalPostProcessors中的BeanPostProcessor会在最后被注册到容器beanFactory中。
【spring源码|Spring源码解析十八】我们总结一下:
文章图片
推荐阅读
- java|微信上传 wx.chooseMedia和wx.uploadFile使用,java springboot后端跑通
- 蓝桥杯|【蓝桥杯】看完这些,还在担心自己拿不到奖()
- 算法解答题目
- 什么是好的错误消息? 讨论一下Java系统中的错误码设计
- 《mongodb经典入门》|四.MongoDB入门-Java操作MongoDB
- 技术|基于canal实现mysql和es增量数据同步
- 《mongodb经典入门》|五.MongoDB入门-SpringData操作MongoDB
- 程序员|普通二本的辛酸Java面试之路,实战篇
- 程序员|【深度思考】普通二本的辛酸Java面试之路,含答案解析