本系列大量参考Spring IOC 容器源码分析、 【死磕 Spring】—– IOC 总结、程序员囧辉的CSDN
文章内容如下:
1.AbstractApplicationContext#refresh()
//设置 BeanFactory 的类加载器,添加几个 BeanPostProcessor,
//手动注册几个特殊的 bean(这边简单提一下注册的AspectJ相关)
2. AbstractApplicationContext#prepareBeanFactory(beanFactory)
// 空方法,交由子类实现。
3.AbstractApplicationContext#postProcessBeanFactory()
//调用IOC容器初始化后的后置方法
4.AbstractApplicationContext#invokeBeanFactoryPostProcessors(beanFactory)
//根据顺序执行BeanDefinitionRegistryPostProcessor 和 BeanFactoryPostProcessor 接口的扩展类方法
4.1 PostProcessorRegistrationDelegate #invokeBeanFactoryPostProcessors
4.1.1 几个参数的介绍
4.1.2 BeanDefinitionRegistryPostProcessor与BeanFactoryPostProcessor的区别
4.1.3 总结PostProcessorRegistrationDelegate中的执行逻辑
4.1.4 BeanDefinitionRegistryPostProcessor的应用场景
//注册 BeanPostProcessor 的实现类
5.AbstractApplicationContext#registerBeanPostProcessors
//注册 BeanPostProcessor 的真正实现类,会把的BeanPostProcessor实现类放到缓存中
5.1PostProcessorRegistrationDelegate #registerBeanPostProcessors(beanFactory,applicationContext)
// 遍历 BeanPostProcessor 数组,注册
5.1.1PostProcessorRegistrationDelegate#registerBeanPostProcessors
//真正注册代码逻辑
5.1.1.1 AbstractBeanFactory#addBeanPostProcessor
6.Spring的BeanFactoryPostProcessor和BeanPostProcessor区别
上一篇说到,Bean 容器实例化完成后,这边重新贴一下refresh方法的代码,继续往下看
1. AbstractApplicationContext#refresh()
public void refresh() throws BeansException, IllegalStateException {
// 来个锁,不然 refresh() 还没结束,你又来个启动或销毁容器的操作,那不就乱套了嘛
synchronized (this.startupShutdownMonitor) {
// 准备工作,记录下容器的启动时间、标记“已启动”状态、处理配置文件中的占位符
prepareRefresh();
// 这步比较关键,这步完成后,配置文件就会解析成一个个 Bean 定义,注册到 BeanFactory 中,
// 当然,这里说的 Bean 还没有初始化,只是配置信息都提取出来了,
// 注册也只是将这些信息都保存到了注册中心(说到底核心是一个 beanName-> beanDefinition 的 map)
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 设置 BeanFactory 的类加载器,添加几个 BeanPostProcessor,手动注册几个特殊的 bean
// 这块待会会展开说
prepareBeanFactory(beanFactory);
try {
// 【这里需要知道 BeanFactoryPostProcessor 这个知识点,Bean 如果实现了此接口,
// 那么在容器初始化以后,Spring 会负责调用里面的 postProcessBeanFactory 方法。】
// 这里是提供给子类的扩展点,到这里的时候,所有的 Bean 都加载、注册完成了,但是都还没有初始化
// 具体的子类可以在这步的时候添加一些特殊的 BeanFactoryPostProcessor 的实现类或做点什么事
postProcessBeanFactory(beanFactory);
// 调用 BeanFactoryPostProcessor 各个实现类的 postProcessBeanFactory(factory) 方法
invokeBeanFactoryPostProcessors(beanFactory);
// 注册 BeanPostProcessor 的实现类,注意看和 BeanFactoryPostProcessor 的区别
// 此接口两个方法: postProcessBeforeInitialization 和 postProcessAfterInitialization
// 两个方法分别在 Bean 初始化之前和初始化之后得到执行。注意,到这里 Bean 还没初始化
registerBeanPostProcessors(beanFactory);
// 初始化当前 ApplicationContext 的 MessageSource,国际化这里就不展开说了,不然没完没了了
initMessageSource();
// 初始化当前 ApplicationContext 的事件广播器,这里也不展开了
initApplicationEventMulticaster();
// 从方法名就可以知道,典型的模板方法(钩子方法),
// 具体的子类可以在这里初始化一些特殊的 Bean(在初始化 singleton beans 之前)
onRefresh();
// 注册事件监听器,监听器需要实现 ApplicationListener 接口。这也不是我们的重点,过
registerListeners();
// 重点,重点,重点
// 初始化所有的 singleton beans
//(lazy-init 的除外)
finishBeanFactoryInitialization(beanFactory);
// 最后,广播事件,ApplicationContext 初始化完成
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
// 销毁已经初始化的 singleton 的 Beans,以免有些 bean 会一直占用资源
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// 把异常往外抛
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
上一篇介绍到obtainFreshBeanFactory()
方法,今天接着来看 prepareBeanFactory(beanFactory)
做了什么。
2.AbstractApplicationContext#prepareBeanFactory(beanFactory) 设置BeanFactory的必要属性
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
//BeanFactory 需要加载类,也就需要类加载器,
// 这里设置为加载当前 ApplicationContext 类的类加载器
beanFactory.setBeanClassLoader(getClassLoader());
// 设置 BeanFactory 的表达式语言处理器,Spring3 增加了表达式语言的支持
// 默认可以使用 #{bean.xxx} 的形式来调用相关属性
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
// 添加 BeanFactory 的属性编辑器 ResourceEditorRegistrar 对象
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// 添加一个 BeanPostProcessor,这个 processor 比较简单:
// 实现了 Aware 接口的 beans 在初始化前后,这个 processor 负责回调,
// 这个我们很常用,如我们会为了获取 ApplicationContext 而 implement ApplicationContextAware
// 注意:它不仅仅回调 ApplicationContextAware,
// 还会负责回调 EnvironmentAware、ResourceLoaderAware 等,看下源码就清楚了
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
// 下面几行的意思就是,如果某个 bean 依赖于以下几个接口的实现类,在自动装配的时候忽略它们,
// Spring 会通过其他方式来处理这些依赖。
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
/**
* 下面几行就是为特殊的几个 bean 赋值,如果有 bean 依赖了以下几个,会注入这边相应的值,
* 之前我们说过,"当前 ApplicationContext 持有一个 BeanFactory",这里解释了第一行。
* ApplicationContext 还继承了 ResourceLoader、ApplicationEventPublisher、MessageSource
* 所以对于这几个依赖,可以赋值为 this,注意 this 是一个 ApplicationContext
* 那这里怎么没看到为 MessageSource 赋值呢?那是因为 MessageSource 被注册成为了一个普通的 bean
*/
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// Register early post-processor for detecting inner beans as ApplicationListeners.
//该BeanPostProcessor检测那些实现了接口ApplicationListener的bean,
//在它们创建时初始化之后,将它们添加到应用上下文的事件多播器上;
//并在这些ApplicationListener bean销毁之前,将它们从应用上下文的事件多播器上移除。
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// 检查容器中是否包含名称为loadTimeWeaver的bean,实际上是增加Aspectj的支持
// AspectJ采用编译期织入、类加载期织入两种方式进行切面的织入
// 类加载期织入简称为LTW(Load Time Weaving),通过特殊的类加载器来代理JVM默认的类加载器实现
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
// 添加BEAN后置处理器:LoadTimeWeaverAwareProcessor
// 在BEAN初始化之前检查BEAN是否实现了LoadTimeWeaverAware接口,
// 如果是,则进行加载时织入,即静态代理。
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
// Set a temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
/**
* 从下面几行代码我们可以知道,Spring 往往很 "智能" 就是因为它会帮我们默认注册一些有用的 bean,
* 我们也可以选择覆盖
*/
// 如果没有定义 "environment" 这个 bean,那么 Spring 会 "手动" 注册一个
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
// 如果没有定义 "systemProperties" 这个 bean,那么 Spring 会 "手动" 注册一个
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
// 如果没有定义 "systemEnvironment" 这个 bean,那么 Spring 会 "手动" 注册一个
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
}
//省略其他代码
}
如这个方法名所说的,这个方法里也是设置了各个beanFactory
所需的功能,这边还检查了一个叫loadTimeWeaver
的bean
,这个是AspectJ
相关bean
,
这里简单提一下
Spring AOP
与AspectJ
的区别
AspectJ在Spring中的使用
3.AbstractApplicationContext#postProcessBeanFactory
在执行完prepareBeanFactory
后,回到refresh
方法,往下执行到了postProcessBeanFactory
方法,值得注意的是,这个是一个空方法,需要子类实现。
注意是子类,与我们所知的实现BeanFactoryPostProcessor
那个扩展接口不是一个东西。
4.AbstractApplicationContext#invokeBeanFactoryPostProcessors(beanFactory) 调用IOC容器初始化后的后置方法
如果子类没有实现,接着调用invokeBeanFactoryPostProcessors
方法,
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
// 执行 BeanFactoryPostProcessor 的钩子方法
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
// AOP 相关
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
这里有一个
getBeanFactoryPostProcessors()
方法用来获取ApplicationContext
里的beanFactoryPostProcessors
,而这个对象是何时注入的我们有机会会在其他篇章说明。这里暂只需要知道有这个值。况且在我们以ClassPathXmlApplicationContext
讲解时也没有这个值注入的场景,这个值在ClassPathXmlApplicationContext
中其实是为空的。
(注意!!:这个beanFactoryPostProcessors
指的是通过硬编码添加到ApplicationContext
这个容器里来的,不是指我们配置的那些,我们配置的那些通过简单的getBeanFactoryPostProcessors
是取不到的,在下面介绍的invokeBeanFactoryPostProcessors
会提到,通过这些扩展接口拿到实现类才能取到。)public List
getBeanFactoryPostProcessors() { return this.beanFactoryPostProcessors; }
4.1 PostProcessorRegistrationDelegate #invokeBeanFactoryPostProcessors 根据顺序执行BeanDefinitionRegistryPostProcessor 和 BeanFactoryPostProcessor 接口的扩展类方法
继续往里面进入看看
invokeBeanFactoryPostProcessors
做了什么,在这里先提前说明一下,这个方法虽然比较长,但是很多都是极其相似的逻辑,搞懂一个情况其他的都懂了,如果几个变量看的比较晕,可以把这串代码拷贝到IDEA上看,点击一个变量后,这个变量被用到的位置都会以浅色背景标识出来。比如这样
final class PostProcessorRegistrationDelegate {
public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List beanFactoryPostProcessors) {
// 已经执行的 BeanDefinitionRegistryPostProcessor 的集合
Set processedBeans = new HashSet<>();
// 1.判断beanFactory是否为BeanDefinitionRegistry,beanFactory为DefaultListableBeanFactory,
// 而DefaultListableBeanFactory实现了BeanDefinitionRegistry接口,因此这边为true
if (beanFactory instanceof BeanDefinitionRegistry) {
// 强转为 BeanDefinitionRegistry 对象
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
// 用于存放普通的BeanFactoryPostProcessor类型的后置处理器
List regularPostProcessors = new ArrayList<>(); // regular 翻译为常规。
// 保存BeanDefinitionRegistryPostProcessor类型的后置处理器
List registryProcessors = new ArrayList<>();
//2.首先处理入参中的beanFactoryPostProcessors
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
//判断我们的后置处理器是不是BeanDefinitionRegistryPostProcessor
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
//强转为 BeanDefinitionRegistryPostProcessor 对象
BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor;
// 对于 BeanDefinitionRegistryPostProcessor 类型,在 BeanFactoryPostProcessor 的基础上还有自定义的方法
//直接执行BeanDefinitionRegistryPostProcessor接口的postProcessBeanDefinitionRegistry方法
registryProcessor.postProcessBeanDefinitionRegistry(registry);
// 添加到我们用于保存的BeanDefinitionRegistryPostProcessor的集合(用于最后执行postProcessBeanFactory方法)
registryProcessors.add(registryProcessor);
} else {
//若没有实现BeanDefinitionRegistryPostProcessor接口,那么他就是BeanFactoryPostProcessor
// 把当前的后置处理器加入到regularPostProcessors中
regularPostProcessors.add(postProcessor);
}
}
// 用于保存本次要执行的BeanDefinitionRegistryPostProcessor
List currentRegistryProcessors = new ArrayList<>();
//3.调用所有实现PriorityOrdered接口的BeanDefinitionRegistryPostProcessor实现类
//找出所有实现BeanDefinitionRegistryPostProcessor接口的Bean的beanName
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
//循环上一步获取的BeanDefinitionRegistryPostProcessor的类型名称
for (String ppName : postProcessorNames) {
//判断是否实现了PriorityOrdered接口的
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
//显示的调用getBean()的方式获取出对应的bean实例,然后加入到currentRegistryProcessors集合中去
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
//将要被执行的加入processedBeans,避免后续重复执行
processedBeans.add(ppName);
}
}
// 进行排序(根据是否实现PriorityOrdered、Ordered接口和order值来排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
// 添加到我们用于保存的BeanDefinitionRegistryPostProcessor的集合(用于最后执行postProcessBeanFactory方法)
registryProcessors.addAll(currentRegistryProcessors);
// 遍历currentRegistryProcessors, 执行postProcessBeanDefinitionRegistry方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
// 执行完毕后, 清空currentRegistryProcessors
currentRegistryProcessors.clear();
//4.调用所有实现了Ordered接口的BeanDefinitionRegistryPostProcessor实现类
//找出所有实现BeanDefinitionRegistryPostProcessor接口的类,
// 这边重复查找是因为执行完上面的BeanDefinitionRegistryPostProcessor,可能会新增了其他的BeanDefinitionRegistryPostProcessor, 因此需要重新查找
//注意,这里的内容与步骤3极其类似,就简略注释了
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
// 校验是否实现了Ordered接口,并且还未执行过
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
// 先排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
// 添加到 registryProcessors 中(用于最后执行postProcessBeanFactory方法)
registryProcessors.addAll(currentRegistryProcessors);
// 后执行
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
// 清空 currentRegistryProcessors
currentRegistryProcessors.clear();
//5.调用没有实现任何优先级接口的BeanDefinitionRegistryPostProcessor,与3.4.也是差不多的
//定义一个重复处理的开关变量 默认值为true
boolean reiterate = true;
//第一次就可以进来
while (reiterate) {
//进入循环马上把开关变量给改为false,顺带一提,refresh是synchronized修饰的,不必在意多线程情况
reiterate = false;
// 获得配置的,BeanDefinitionRegistryPostProcessor 数组
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
// 不包含,说明还未执行过
if (!processedBeans.contains(ppName)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName); // 添加 processedBeans 中
reiterate = true;
}
}
// 先排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
// 添加到 registryProcessors 中(用于最后执行postProcessBeanFactory方法)
registryProcessors.addAll(currentRegistryProcessors);
// 执行 currentRegistryProcessors
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
// 清空 currentRegistryProcessors
currentRegistryProcessors.clear();
}
//6.调用所有BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法
// (BeanDefinitionRegistryPostProcessor继承自BeanFactoryPostProcessor)
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
//7.调用入参beanFactoryPostProcessors中的普通BeanFactoryPostProcessor的postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
} else {
//若当前的beanFactory没有实现了BeanDefinitionRegistry 直接调用入参beanFactoryPostProcessors接口的方法进行后置处理
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
// 到这里 , 入参beanFactoryPostProcessors和容器中的所有BeanDefinitionRegistryPostProcessor已经全部处理完毕,
// 下面开始处理容器中的所有BeanFactoryPostProcessor
// 8.找出所有实现BeanFactoryPostProcessor接口的类
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// 用于存放实现了PriorityOrdered接口的BeanFactoryPostProcessor
List priorityOrderedPostProcessors = new ArrayList<>();
// 用于存放实现了Ordered接口的BeanFactoryPostProcessor的beanName
List orderedPostProcessorNames = new ArrayList<>();
// 用于存放普通BeanFactoryPostProcessor的beanName
List nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
// 跳过已经执行过的
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
}
// 添加实现了PriorityOrdered接口的BeanFactoryPostProcesso,并在此一举做好了实例化
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
// 添加实现了Ordered接口的BeanFactoryPostProcessor的beanName
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
} else {
// 添加剩下的普通BeanFactoryPostProcessor的beanName
nonOrderedPostProcessorNames.add(ppName);
}
}
//9.调用所有实现PriorityOrdered接口的BeanFactoryPostProcessor,
// 这里的处理与上面的步骤3、4、5处理也极其类似
// 对priorityOrderedPostProcessors排序
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
//遍历priorityOrderedPostProcessors, 执行postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
//10.调用所有实现Ordered接口的BeanFactoryPostProcessor
List orderedPostProcessors = new ArrayList<>();
for (String postProcessorName : orderedPostProcessorNames) {
//获取postProcessorName对应的bean实例, 添加到orderedPostProcessors, 准备执行
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
// 先排序
sortPostProcessors(orderedPostProcessors, beanFactory);
// 后执行
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
//11.调用所有剩下的BeanFactoryPostProcessor
List nonOrderedPostProcessors = new ArrayList<>();
for (String postProcessorName : nonOrderedPostProcessorNames) {
//获取postProcessorName对应的bean实例, 添加到nonOrderedPostProcessors, 准备执行
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
// 遍历nonOrderedPostProcessors, 执行postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
//清除元数据缓存(mergedBeanDefinitions、allBeanNamesByType、singletonBeanNamesByType),
// 因为后处理器可能已经修改了原始元数据,例如, 替换值中的占位符...
beanFactory.clearMetadataCache();
}
//省略其他代码
}
4.1.1 几个参数的介绍
入参
beanFactoryPostProcessors
:拿的是AbstractApplicationContext
类的beanFactoryPostProcessors
属性值,也就是在之前已经添加到beanFactoryPostProcessors
中的BeanFactoryPostProcessor
。
BeanDefinitionRegistryPostProcessor
接口实现类:实现了BeanDefinitionRegistryPostProcessor
接口,并且注册到Spring IoC
容器中。常规
BeanFactoryPostProcessor
接口实现类:实现了BeanFactoryPostProcessor
接口,并且注册到Spring IoC
容器中。
4.1.2 BeanDefinitionRegistryPostProcessor与BeanFactoryPostProcessor的区别
BeanDefinitionRegistryPostProcessor
接口继承了BeanFactoryPostProcessor
,这里对于
BeanDefinitionRegistryPostProcessor
接口,既可以获取和修改BeanDefinition
的元数据,也可以实现 BeanDefinition 的注册、移除等操作(这个接口主要也是为了增减BeanDefinition,虽然他也可以改变,但是改变交由BeanFactoryPostProcessor来做会使目的更明确)。这两个接口的简单介绍可参考该链接:Spring处理器及其相关的使用场景
4.1.3 总结PostProcessorRegistrationDelegate中的执行逻辑
概括来说,对于执行顺序,
postProcessBeanDefinitionRegistry
方法优于postProcessBeanFactory
方法
BeanDefinitionRegistryPostProcessor
的实现类优于BeanFactoryPostProcessor
的实现类,
BeanFactory
早期被硬编码注入的参数优于我们自己实现的接口
实现了PriorityOrdered
接口的 优于 实现了Ordered
接口的(同实现需要比较Order
值) 优于两者都没实现的以上的比较顺序分先后。
详细执行顺序如下
第一优先级:入参beanFactoryPostProcessors
中的BeanDefinitionRegistryPostProcessor
, 调用postProcessBeanDefinitionRegistry
方法(2.)。
第二优先级:BeanDefinitionRegistryPostProcessor
接口实现类,并且实现了PriorityOrdered
接口,调用postProcessBeanDefinitionRegistry
方法(3.)。
第三优先级:BeanDefinitionRegistryPostProcessor
接口实现类,并且实现了Ordered
接口,调用postProcessBeanDefinitionRegistry
方法(4.)。
第四优先级:除去第二优先级和第三优先级,剩余的BeanDefinitionRegistryPostProcessor
接口实现类,调用postProcessBeanDefinitionRegistry
方法(5.)。第五优先级:所有
BeanDefinitionRegistryPostProcessor
接口实现类,调用postProcessBeanFactory
方法(6.)。
第六优先级:入参beanFactoryPostProcessors
中的常规BeanFactoryPostProcessor
,调用postProcessBeanFactory
方法(7.)。
第七优先级:常规BeanFactoryPostProcessor
接口实现类,并且实现了PriorityOrdered
接口,调用postProcessBeanFactory
方法(9.)。
第八优先级:常规BeanFactoryPostProcessor
接口实现类,并且实现了Ordered
接口,调用postProcessBeanFactory
方法(10.)。
第九优先级:除去第七优先级和第八优先级,剩余的常规BeanFactoryPostProcessor
接口的实现类,调用postProcessBeanFactory
方法(11.)。参考: Spring IoC源码学习:invokeBeanFactoryPostProcessors 详解
4.1.4 BeanDefinitionRegistryPostProcessor的应用场景
这里还值得说一下BeanDefinitionRegistryPostProcessor
的一个应用场景——Mybatis
。
我们通常在使用
Mybatis
+Spring
时,经常用到的org.mybatis.spring.mapper.MapperScannerConfigurer
就是一个BeanDefinitionRegistryPostProcessor
。MapperScannerConfigurer
在postProcessBeanDefinitionRegistry
方法中进行了一些操作,主要是:扫描basePackage
指定的目录,将该目录下的类(通常是DAO/MAPPER
接口)封装成BeanDefinition
并加载到BeanFactory
中。因此,我们可以看到我们项目中的DAO(MAPPER)
接口,通常都没有使用注解或XML
的方式注册到Spring
容器,但是我们还是可以在Service
服务中,使用@Autowire
注解来将其注入到Service
中,就是因为这个原因。
5.AbstractApplicationContext#registerBeanPostProcessors 注册 BeanPostProcessor 的实现类
说完了invokeBeanFactoryPostProcessors()
,接下来说refresh
方法里的调用的下一个方法registerBeanPostProcessors()
,这个方法用于
注册拦截 Bean
创建的 BeanPostProcessor
,将所有实现了BeanPostProcessor
接口的类加载到 BeanFactory
中。注意这里只是注册,真正的调用在 #getBean(...)
的时,即Bean
创建的时候。
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
显然调用的逻辑不在这,继续往下看.
5.1PostProcessorRegistrationDelegate #registerBeanPostProcessors(beanFactory,applicationContext) 注册 BeanPostProcessor 的真正实现类,会把的BeanPostProcessor实现类放到缓存中
final class PostProcessorRegistrationDelegate {
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
// 1.找出所有实现BeanPostProcessor接口的类
// 这些 beanName 都已经全部加载到容器中去,但是没有实例化
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.
// 记录所有的beanProcessor数量
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
// 2.注册 BeanPostProcessorChecker,它主要是用于在 BeanPostProcessor 实例化期间记录日志
// 当 Spring 中高配置的后置处理器还没有注册就已经开始了 bean 的实例化过程,这个时候便会打印 BeanPostProcessorChecker 中的内容
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// Separate between BeanPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
//3.定义不同的变量用于区分: 实现PriorityOrdered接口的BeanPostProcessor、实现Ordered接口的BeanPostProcessor、普通BeanPostProcessor
// priorityOrderedPostProcessors: 用于存放实现PriorityOrdered接口的BeanPostProcessor
List priorityOrderedPostProcessors = new ArrayList<>();
// internalPostProcessors: 用于存放Spring内部的BeanPostProcessor
List internalPostProcessors = new ArrayList<>();
// orderedPostProcessorNames: 用于存放实现Ordered接口的BeanPostProcessor的beanName
List orderedPostProcessorNames = new ArrayList<>();
// nonOrderedPostProcessorNames: 用于存放普通BeanPostProcessor的beanName
List nonOrderedPostProcessorNames = new ArrayList<>();
//4.遍历postProcessorNames, 将BeanPostProcessors按上述的四个定义的变量区分开
for (String ppName : postProcessorNames) {
//按 PriorityOrdered 接口区分
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
// 调用 getBean 获取 bean 实例对象
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
//如果ppName对应的Bean实例也实现了MergedBeanDefinitionPostProcessor接口
if (pp instanceof MergedBeanDefinitionPostProcessor) {
//则将ppName对应的Bean实例添加到internalPostProcessors
internalPostProcessors.add(pp);
}
//按 Ordered 接口区分
} else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
} else {
//剩下的就是什么都没实现,普通的BeanPostProcessor
nonOrderedPostProcessorNames.add(ppName);
}
}
// 5.注册实现PriorityOrdered接口的BeanPostProcessors
// 对priorityOrderedPostProcessors进行排序
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
// 注册priorityOrderedPostProcessors
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// 6.注册实现Ordered接口的BeanPostProcessors
List orderedPostProcessors = new ArrayList<>();
//拿到ppName对应的BeanPostProcessor实例对象
for (String ppName : orderedPostProcessorNames) {
//将ppName对应的BeanPostProcessor实例对象添加到orderedPostProcessors, 准备执行注册
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
//如果ppName对应的Bean实例也实现了MergedBeanDefinitionPostProcessor接口,
//则将ppName对应的Bean实例添加到internalPostProcessors
internalPostProcessors.add(pp);
}
}
// 对orderedPostProcessors进行排序
sortPostProcessors(orderedPostProcessors, beanFactory);
// 注册orderedPostProcessors
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// 7.注册所有常规的BeanPostProcessors(过程与6类似)
List nonOrderedPostProcessors = new ArrayList<>();
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
// 注册,无需排序(因为没有实现排序的接口嘛)
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
//8.最后, 重新注册所有内部BeanPostProcessors(相当于内部的BeanPostProcessor会被移到处理器链的末尾)
// 对internalPostProcessors进行排序
sortPostProcessors(internalPostProcessors, beanFactory);
// 注册internalPostProcessors
registerBeanPostProcessors(beanFactory, internalPostProcessors);
//9.重新注册ApplicationListenerDetector(跟8类似,主要是为了移动到处理器链的末尾)
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
//省略其他代码
}
方法的逻辑与上面介绍的
invokeBeanFactoryPostProcessors
也很类似,排序也是一样的逻辑,上面那个方法看懂了这个读下来会没有丝毫停滞,所以就不作详细介绍了。有一点不同就是,上面介绍的invokeBeanFactoryPostProcessors
方法会直接调用BeanFactoryPostProcessor
实现类的方法,而 此次介绍的
registerBeanPostProcessors
方法只是将BeanPostProcessor
实现类注册到BeanFactory
的beanPostProcessors
缓存中。
5.1.1PostProcessorRegistrationDelegate#registerBeanPostProcessors 遍历 BeanPostProcessor 数组,注册
注册的方法代码如下:
private static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, List postProcessors) {
// 遍历 BeanPostProcessor 数组,注册
for (BeanPostProcessor postProcessor : postProcessors) {
beanFactory.addBeanPostProcessor(postProcessor);
}
}
接着往下调用,调用到了AbstractBeanFactory#addBeanPostProcessor
5.1.1.1 AbstractBeanFactory#addBeanPostProcessor 真正注册代码逻辑
@Override
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
// 1.如果beanPostProcessor已经存在则移除(可以起到排序的效果,beanPostProcessor可能本来在前面,移除再添加,则变到最后面)
this.beanPostProcessors.remove(beanPostProcessor);
// 2.将beanPostProcessor添加到beanPostProcessors缓存
this.beanPostProcessors.add(beanPostProcessor);
if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
// 3.如果beanPostProcessor是InstantiationAwareBeanPostProcessor, 则将hasInstantiationAwareBeanPostProcessors设置为true,
// 该变量用于指示beanFactory是否已注册过InstantiationAwareBeanPostProcessors
this.hasInstantiationAwareBeanPostProcessors = true;
}
if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
// 4.如果beanPostProcessor是DestructionAwareBeanPostProcessor, 则将hasInstantiationAwareBeanPostProcessors设置为true,
// 该变量用于指示beanFactory是否已注册过DestructionAwareBeanPostProcessor
this.hasDestructionAwareBeanPostProcessors = true;
}
}
该方法作用就是将
BeanPostProcessor
添加到beanPostProcessors
缓存,这边的先移除再添加,主要是起一个排序的作用。而hasInstantiationAwareBeanPostProcessors
和hasDestructionAwareBeanPostProcessors
变量用于指示beanFactory
是否已注册过InstantiationAwareBeanPostProcessors
和DestructionAwareBeanPostProcessor
,在之后的 IoC 创建过程会用到这两个变量,这边先有个印象。
6.Spring的BeanFactoryPostProcessor和BeanPostProcessor区别
Spring的BeanFactoryPostProcessor和BeanPostProcessor区别
1.
BeanPostProcessor
实现类具体的 “出场时机” 在创建 bean 实例时,执行初始化方法前后。postProcessBeforeInitialization
方法在执行初始化方法前被调用,postProcessAfterInitialization
方法在执行初始化方法后被调用。2.
BeanPostProcessor
实现类和BeanFactoryPostProcessor
实现类一样,也可以通过实现PriorityOrdered
、Ordered
接口来调整自己的优先级。3.
registerBeanPostProcessors
方法和invokeBeanFactoryPostProcessors
也会触发bean
实例的创建(这两个方法里都会调用到getBean方法,这个是bean创建的主要方法)