文章目录
- 2.1 refresh()中调用registerBeanPostProcessors()方法
- 2.2 registerBeanPostProcessors()中调用PostProcessorRegistrationDelegate.registerBeanPostProcessors()
- 2.3 源码解析:PostProcessorRegistrationDelegate.registerBeanPostProcessors()方法
- 3.1 refresh()中调用finishBeanFactoryInitialization()方法(第11个方法,倒数第二个方法)
- 3.2 源码解析:finishBeanFactoryInitialization()方法
- 3.3 源码解析:initializeBean() bean初始化/实例化
- 3.4 源码解析:applyBeanPostProcessorsBeforeInitialization(),执行每一个BeanPostProcessor的方法
- 3.5 源码解析:applyBeanPostProcessorsAfterInitialization,执行每一个BeanPostProcessor的方法
- 3.6 这些MergedBeanDefinitionPostProcessor实现类在spring容器中是何处使用的呢?源码解析:applyMergedBeanDefinitionPostProcessors
- 4.1 注册到spring容器,核心方法:registerBeanPostProcessors()(第6个方法)
- 4.2 Spring启动时实例化,核心方法:finishBeanFactoryInitialization()方法(第11个方法,倒数第二个方法)
- 五、小结
一、前言
BeanPostProcessor接口的作用:控制bean,设置bean实例,这是是学习的核心指导,要记住。
好了,我们先到Spring源码中找到实现了BeanPostProcessor接口的类
控制bean的两种扩展方式,两种方式可以对bean做控制(例如修改某个成员变量):
- 改变bean的定义(BeanFactoryPostProcessor接口) ,可以想象成修改了class文件,这样实例化出来的每个对象都变了;(在【源码解析008 里面看到过了】)
- 只改变实例化的对象(BeanPostProcessor接口);
本文我们来研究第二种:改变实例化的对象;
本文两个内容:
- spring源码分析,了解BeanPostProcessor接口的实现类如何被注册到spring容器;
- spring源码分析,了解已经注册到spring环境的BeanPostProcessor实现类如何被使用;
二、源码分析:BeanPostProcessor接口的实现类如何被注册到spring容器
2.1 refresh()中调用registerBeanPostProcessors()方法
从spring容器的初始化代码看起吧,看AbstractApplicationContext类的refresh方法,如下图所示,红框中的方法负责将BeanPostProcessor接口的实现类注册到spring容器:
2.2 registerBeanPostProcessors()中调用PostProcessorRegistrationDelegate.registerBeanPostProcessors()
展开registerBeanPostProcessors方法,发现是委托PostProcessorRegistrationDelegate类的静态方法registerBeanPostProcessors来完成注册工作的:
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
2.3 源码解析:PostProcessorRegistrationDelegate.registerBeanPostProcessors()方法
展开PostProcessorRegistrationDelegate.registerBeanPostProcessors方法,里面的代码逻辑简洁整齐,意图目的一目了然:
金手指1:加一是因为方法末尾会注册一个ApplicationListenerDetector接口的实现类。
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
//获取所有实现BeanPostProcessor接口的bean的名称
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
//注意,此时尽管注册操作还没有开始,但是之前已经有一些特殊的bean已经注册进来了,
//详情请看AbstractApplicationContext类的prepareBeanFactory方法(refresh()第一个方法),
//因此getBeanPostProcessorCount()方法返回的数量并不为零,
//加一是因为方法末尾会注册一个ApplicationListenerDetector接口的实现类
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
//这里的BeanPostProcessorChecker也是个BeanPostProcessor的实现类,用于每个bean的初始化完成后,做一些简单的检查
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
//如果这些bean还实现了PriorityOrdered接口(在意执行顺序),就全部放入集合priorityOrderedPostProcessors
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
//集合internalPostProcessors,用来存放同时实现了PriorityOrdered和MergedBeanDefinitionPostProcessor接口的bean
List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();
//集合orderedPostProcessorNames用来存放实现了Ordered接口的bean的名称(在意执行顺序)
List<String> orderedPostProcessorNames = new ArrayList<String>();
//集合nonOrderedPostProcessorNames用来存放即没实现PriorityOrdered接口,也没有实现Ordered接口的bean的名称(不关心执行顺序)
List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
for (String ppName : postProcessorNames) { // 对实参遍历
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
//实现了PriorityOrdered接口的bean,都放入集合priorityOrderedPostProcessors
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
//同时实现PriorityOrdered接口和MergedBeanDefinitionPostProcessor接口的bean,放入internalPostProcessors集合
internalPostProcessors.add(pp);
}
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
//未实现实现了PriorityOrdered接口,但是实现Ordered接口的bean,将其名称都放入orderedPostProcessorNames集合
orderedPostProcessorNames.add(ppName);
}
else {
//既没实现PriorityOrdered接口,也没有实现Ordered接口的bean,将其名称放入nonOrderedPostProcessorNames集合
nonOrderedPostProcessorNames.add(ppName);
}
}
//实现了PriorityOrdered接口的bean排序
OrderComparator.sort(priorityOrderedPostProcessors);
//实现了PriorityOrdered接口的bean,注册到容器
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>();
//处理所有实现了Ordered接口的bean
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
//前面将所有实现了PriorityOrdered和MergedBeanDefinitionPostProcessor的bean放入internalPostProcessors,
//此处将所有实现了Ordered和MergedBeanDefinitionPostProcessor的bean放入internalPostProcessors
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
//实现了Ordered接口的bean排序
OrderComparator.sort(orderedPostProcessors);
//注册到容器
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
//此处将其余实现了MergedBeanDefinitionPostProcessor的bean放入internalPostProcessors
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
//注册到容器
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
OrderComparator.sort(internalPostProcessors);
//既没实现PriorityOrdered接口,也没有实现Ordered接口的bean,将所有实现了MergedBeanDefinitionPostProcessor接口的bean也注册到容器
registerBeanPostProcessors(beanFactory, internalPostProcessors);
//创建一个ApplicationListenerDetector对象并且注册到容器,这就是前面计算beanProcessorTargetCount的值时加一的原因
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
金手指1:关于MergedBeanDefinitionPostProcessor
internalPostProcessors只是在实现了其余三个接口中的任意一个的基础上实现了MergedBeanDefinitionPostProcessor才添加 good 第一段代码简化了,展开会好理解很多。
金手指2:关于MergedBeanDefinitionPostProcessor
MergedBeanDefinitionPostProcessor重复注册问题在源码registerBeanPostProcessors()方法里有处理的方法
以上代码已加注释,就不多解读了,有一点需要注意:对于实现了MergedBeanDefinitionPostProcessor接口的bean,在前面几次调用registerBeanPostProcessors方法的时候已经注册过了,那么在最后执行的registerBeanPostProcessors(beanFactory, internalPostProcessors),岂不是将一个bean注册了多次?
为了弄清楚这个问题需要看registerBeanPostProcessors方法:
private static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {
for (BeanPostProcessor postProcessor : postProcessors) {
//对每个bean都调用beanFactory.addBeanPostProcessor方法来注册
beanFactory.addBeanPostProcessor(postProcessor);
}
}
addBeanPostProcessor方法的代码在AbstractApplicationContext类中,如下所示,先删除再添加,这样反复注册也没有问题:
@Override
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
//如果已经注册,就先删除掉,没注册,删除操作无用
this.beanPostProcessors.remove(beanPostProcessor);
//再注册
this.beanPostProcessors.add(beanPostProcessor);
if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
this.hasInstantiationAwareBeanPostProcessors = true;
}
if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
this.hasDestructionAwareBeanPostProcessors = true;
}
}
至此,我们已经弄清楚了BeanPostProcessor实现类的bean注册到spring容器的逻辑,接下来看看spring容器如何使用这些bean;
三、源码分析,BeanPostProcessor实现类如何被使用
3.1 refresh()中调用finishBeanFactoryInitialization()方法(第11个方法,倒数第二个方法)
要弄清楚BeanPostProcessor接口的实现类是在哪里被用到的,还是从负责容器初始化的AbstractApplicationContext类的refresh方法看起,如下图红框中的finishBeanFactoryInitialization方法,就是负责实例化和初始化bean的:
3.2 源码解析:finishBeanFactoryInitialization()方法
从finishBeanFactoryInitialization方法到BeanPostProcessor的实现类被使用,中间有多层逻辑和调用,篇幅所限就不逐个展开了,直接列出堆栈信息,您可以根据此信息去查看对应源码:
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean() bean初始化/实例化
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean() 这里有一个bean属性设置
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean() 创建bean newInstance()
org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject()
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton()
org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean()
org.springframework.beans.factory.support.AbstractBeanFactory.getBean()
org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons()
org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization()
org.springframework.context.support.AbstractApplicationContext.refresh()
org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh()
org.springframework.boot.SpringApplication.refresh()
org.springframework.boot.SpringApplication.refreshContext()
org.springframework.boot.SpringApplication.run()
org.springframework.boot.SpringApplication.run()
org.springframework.boot.SpringApplication.run()
3.3 源码解析:initializeBean() bean初始化/实例化
根据上述堆栈信息,直接查看AbstractAutowireCapableBeanFactory类的initializeBean()方法:
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
// 1、调用 invokeAwareMethods(beanName, bean);
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
invokeAwareMethods(beanName, bean);
return null;
}
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 2、对已经实例化的bean,在初始化前用BeanPostProcessor实现类去处理
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 3、bean的初始化(核心方法)
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()) {
// 4、对已经实例化的bean,在初始化后用BeanPostProcessor实现类去处理
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
如上所示,我们最关注的代码是applyBeanPostProcessorsBeforeInitialization和applyBeanPostProcessorsAfterInitialization这两个方法,它们分别在bean的初始化方法invokeInitMethods的前后被执行;
3.4 源码解析:applyBeanPostProcessorsBeforeInitialization(),执行每一个BeanPostProcessor的方法
先看看applyBeanPostProcessorsBeforeInitialization方法,逻辑非常简单,就是取出所有已注册的BeanPostProcessor实现类,执行其postProcessBeforeInitialization方法,入参是当前正在做实例化和初始化的bean实例:
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
//逐一执行每个BeanPostProcessor实现类的postProcessBeforeInitialization方法
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
result = beanProcessor.postProcessBeforeInitialization(result, beanName);
if (result == null) {
return result;
}
}
return result;
}
3.5 源码解析:applyBeanPostProcessorsAfterInitialization,执行每一个BeanPostProcessor的方法
在invokeInitMethods方法执行完毕后会执行applyBeanPostProcessorsAfterInitialization方法,代码如下,与applyBeanPostProcessorsBeforeInitialization如出一辙,仅有的不同是调用的beanProcessor的方法变成了postProcessAfterInitialization:
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
//逐一执行每个BeanPostProcessor实现类的postProcessAfterInitialization方法
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
result = beanProcessor.postProcessAfterInitialization(result, beanName);
if (result == null) {
return result;
}
}
return result;
}
3.6 这些MergedBeanDefinitionPostProcessor实现类在spring容器中是何处使用的呢?源码解析:applyMergedBeanDefinitionPostProcessors
问题:以上就是spring容器初始化过程中对BeanPostProcessor实现类的使用场景,此时还剩一点疑问需要澄清:在分析注册过程的时候,曾看到实现MergedBeanDefinitionPostProcessor接口的bean是最后注册的,那么这些MergedBeanDefinitionPostProcessor实现类在spring容器中是何处使用的呢?
为了搞清这个问题,来看看AbstractAutowireCapableBeanFactory类的doCreateBean方法,前面我们分析的initializeBean方法就是在这里面被调用的:
如上图所示,红框中就是用所有MergedBeanDefinitionPostProcessor实现类去处理当前正在实例化的bean,然后才会执行绿框中的initializeBean方法(里面是我们刚才分析的bean的初始化,BeanPostProcessor实现类被使用的逻辑);
来看看红框中的applyMergedBeanDefinitionPostProcessors方法,主要目的是处理特殊的合成bean的定义类:
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName)
throws BeansException {
try {
//取出每个注册的BeanPostProcessor实现类
for (BeanPostProcessor bp : getBeanPostProcessors()) {
//只有实现了MergedBeanDefinitionPostProcessor接口才执行
if (bp instanceof MergedBeanDefinitionPostProcessor) {
MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
//执行postProcessMergedBeanDefinition
bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
}
}
}
catch (Exception ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing failed of bean type [" + beanType + "] failed", ex);
}
}
四、面试金手指(面试语言组织)
至此,我们对BeanPostProcessor有关的源码分析就完成了,小结一下:
4.1 注册到spring容器,核心方法:registerBeanPostProcessors()(第6个方法)
核心方法:registerBeanPostProcessors(),这里展示逻辑:
- 初始化时,spring容器有特别处理,会直接调用beanFactory.addBeanPostProcessor进行注册(例如AbstractApplicationContext类的prepareBeanFactory方法中就有);
- 找出所有实现了BeanPostProcessor接口的bean,注册到容器,注册顺序如下:
第一:实现了PriorityOrdered接口的,排序后;
第二:实现了Ordered接口的,排序后;
第三:既没实现PriorityOrdered接口,也没有实现Ordered接口的;
第四:实现了MergedBeanDefinitionPostProcessor接口的(这些也按照PriorityOrdered、Ordered等逻辑排列过顺序);
第五:实例化一个ApplicationListenerDetector对象;
金手指1:关于MergedBeanDefinitionPostProcessor
internalPostProcessors只是在实现了其余三个接口中的任意一个的基础上实现了MergedBeanDefinitionPostProcessor才添加 good 第一段代码简化了,展开会好理解很多。
金手指2:关于MergedBeanDefinitionPostProcessor
MergedBeanDefinitionPostProcessor重复注册问题在源码registerBeanPostProcessors()方法里有处理的方法
4.2 Spring启动时实例化,核心方法:finishBeanFactoryInitialization()方法(第11个方法,倒数第二个方法)
小结:good
- 实例化bean的时候,对于每个bean,先用MergedBeanDefinitionPostProcessor实现类的postProcessMergedBeanDefinition方法处理每个bean的定义类;
- 再用BeanPostProcessor的postProcessBeforeInitialization方法处理每个bean实例;
- bean实例初始化;
- 用BeanPostProcessor的postProcessAfterInitialization方法处理每个bean实例;
第二部分是在AbstractApplicationContext类中的refresh()方法第6 个registerBeanPostProcessors()中执行的?
回答:就是不断通过beanName,得到BeanPostProcessor,放到list里面,然后排序,最后注册到spring ioc容器。
第三部分是在AbstractApplicationContext类中的refresh()方法中的finishBeanFactoryInitialization(beanFactory);中执行的,那些注册到spring ioc容器中的BeanPostProcessor怎样使用?
回答:
(1)doCreateBean()中调用initializeBean()内部,applyBeanPostProcessorsBeforeInitialization(),执行每一个BeanPostProcessor的方法;
(2)doCreateBean()中调用initializeBean()内部,applyBeanPostProcessorsAfterInitialization,执行每一个BeanPostProcessor的方法。
(3)这些MergedBeanDefinitionPostProcessor实现类在spring容器中是何处使用的呢?源码解析:doCreateBean()中调用initializeBean()之前,applyMergedBeanDefinitionPostProcessors
五、小结
BeanPostProcessor接口,完成。
天天打码,天天进步!!!