相关文章:
Spring源码系列之容器启动流程 建议先阅读这篇文章
系列文章:
【spring源码】01.Spring源码整体脉络介绍及源码编译–spring笔记
【spring源码】02.Ioc容器加载过程-Bean的生命周期源码深度剖析–spring笔记
【spring源码】Spring IoC源码学习:invokeBeanFactoryPostProcessors 详解
【spring源码 4.3.7】ConfigurationClassPostProcessor
【spring源码 4.3.7】Spring IoC源码学习:registerBeanPostProcessors() 详解
【spring源码 4.3.7】Spring IoC源码学习:finishBeanFactoryInitialization() 详解
【spring源码 4.3.7】Spring IoC源码学习:BeanFactory.getBean() 详解
【spring源码 4.3.7】Spring IoC源码学习:AbstractAutowireCapableBeanFactory.populateBean()
【spring源码 4.3.7】Spring IoC源码学习:AbstractAutowireCapableBeanFactory.initializeBean() 初始化生命周期
前言
bean实例化的周期图:
-
在实例化bean之前,也会有个
BeanFactoryPostProcessor
接口实例的链式集合,用于处理bean定义; -
bean的定义固化下来后,就进行new 实例化的操作
-
在new 的过程中,就会有很多步骤,例如实现了Aware接口实例的一组集合,类似链式,逐一处理一遍,接着是实现了
BeanPostProcessor
接口实例的一组集合,类似链式,逐一处理一遍重点来了,这个预置的处理链时是怎么生成的?答案就是 在一个项目启动时,会预先加载一些bean定义,这些bean根据类型,会加入不同的处理链,而【spring注解】context:annotation-config和context:component-scan区别 内的 context:annotation-config和context:component-scan语法就是在其定义的范围内的,如果实现了BeanFactoryPostProcessor和BeanPostProcessor,这些bean 就被当做处理器,加入集合。BeanFactoryPostProcessor处理器链的加载过程就是本篇文章的目的
概述
* * * * BeanFactoryPostProcessor接口的唯一内置实现类是ConfigurationClassPostProcessor,详情参见 【spring源码 4.3.7】ConfigurationClassPostProcessor,并且这个类的优先级是最高的,在invokeBeanFactoryPostProcessors()方法中优先执行。
整体的流程图:
本方法会实例化和调用所有 BeanFactoryPostProcessor
(包括其子类 BeanDefinitionRegistryPostProcessor
,子类优先级高,会优先处理)。
BeanFactoryPostProcessor
接口是 Spring 初始化 BeanFactory 时对外暴露的扩展点,Spring IoC 容器允许 BeanFactoryPostProcessor 在容器实例化任何 bean 之前读取 bean 的定义,并可以修改它
。
BeanFactoryPostProcessor 详细用法参见《Spring的BeanFactoryPostProcessor和BeanPostProcessor》
BeanDefinitionRegistryPostProcessor
继承自 BeanFactoryPostProcessor
接口(比 BeanFactoryPostProcessor 具有更高的优先级执行
),那么一定要做些事情,子接口前缀BeanDefinitionRegistry
顾名思义,负责BeanDefinition的注册,主要用来在常规的 BeanFactoryPostProcessor
检测开始之前注册其他 bean 定义。
特别是,你可以通过 BeanDefinitionRegistryPostProcessor 来注册一些常规的 BeanFactoryPostProcessor,因为此时所有常规的 BeanFactoryPostProcessor 都还没开始被处理。
注:这边的 “常规 BeanFactoryPostProcessor” 主要用来跟 BeanDefinitionRegistryPostProcessor 区分。
因此,invokeBeanFactoryPostProcessors()主要功能就是寻找实现BeanFactoryPostProcessor的子类,并调用他们的重载方法,比如子类BeanDefinitionRegistryPostProcessor 负责注册bean(仅仅是注册,不是实例化,但是也需要提前实例化一部分bean)。
1. invokeBeanFactoryPostProcessors
首先我们回到 AbstractApplicationContext.refresh()
方法,找到代码:invokeBeanFactoryPostProcessors(beanFactory)
,单击该行代码跳转到具体的实现。
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
// 【1】.getBeanFactoryPostProcessors(): 拿到当前应用上下文beanFactoryPostProcessors变量中的值
// 【2】.invokeBeanFactoryPostProcessors(): 实例化并调用所有已注册的BeanFactoryPostProcessor
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
【1】.拿到当前应用上下文 beanFactoryPostProcessors 变量中的值,见代码块1详解。
【2】.实例化并调用所有已注册的 BeanFactoryPostProcessor,见代码块2详解。
1.1 代码块1:getBeanFactoryPostProcessors()
public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() {
//成员变量,List<BeanFactoryPostProcessor>结构的集合
return this.beanFactoryPostProcessors;
}
这边 getBeanFactoryPostProcessors() 会拿到当前应用上下文中已经注册的 BeanFactoryPostProcessor,在默认情况下,this.beanFactoryPostProcessors ()是返回空的。
如何添加自定义 BeanFactoryPostProcessor 到 this.beanFactoryPostProcessors 变量中了?
如果还有印象的话,我们在 Spring IoC:refresh前的环境准备 中的代码块12介绍过 customizeContext 方法,该方法是 Spring 提供给开发者的一个扩展点,用于自定义应用上下文,并且在 refresh() 方法前就被调用。在这边就可以通过该方法来添加自定义的 BeanFactoryPostProcessor。
简单来说,内置的BeanFactoryPostProcessor实现类或者定义@Component(等待spring扫描的实现了BeanFactoryPostProcessor接口的)的实现类,不在 this.beanFactoryPostProcessors 变量中,该变量存储的是其他方式定义的BeanFactoryPostProcessor。
这种其他方式定义的BeanFactoryPostProcessor实现类使用方式如下:
1.新建一个 ApplicationContextInitializer
的实现类 MySpringApplicationContextInitializer ,并在 initialize 方法中写我们的逻辑。
package com.joonwhee.open.demo.spring;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
/**
* @author joonwhee
* @date 2019/1/19
*/
public class MySpringApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
FirstBeanDefinitionRegistryPostProcessor firstBeanDefinitionRegistryPostProcessor = new FirstBeanDefinitionRegistryPostProcessor();
// 将自定义的firstBeanDefinitionRegistryPostProcessor添加到应用上下文中
applicationContext.addBeanFactoryPostProcessor(firstBeanDefinitionRegistryPostProcessor);
// ...自定义操作
System.out.println("SpringApplicationContextInitializer#initialize");
}
}
2.将 MySpringApplicationContextInitializer 作为初始化参数 contextInitializerClasses 配置到 web.xml 中。
<context-param>
<param-name>contextInitializerClasses</param-name>
<param-value>
com.joonwhee.open.demo.spring.MySpringApplicationContextInitializer
</param-value>
</context-param>
这样,在启动应用时,FirstBeanDefinitionRegistryPostProcessor 就会被添加到 this.beanFactoryPostProcessors集合 中。
1.2 代码块2:PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors()
搜索【2】处代码
总体流程图:
final class PostProcessorRegistrationDelegate {
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// 定义已经处理完成的Bean的集合,当后处理完成后,加入该集合里面
Set<String> processedBeans = new HashSet<>();
//[1]beanFactory是DefaultListableBeanFactory,是BeanDefinitionRegistry的实现类,所以肯定满足if
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
//regularPostProcessors 专门用来存放扩展父接口BeanFactoryPostProcessor的实现类(但是与其子类BeanDefinitionRegistryPostProcessor区分开)
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
//registryProcessors 专门用来存放子类BeanDefinitionRegistryPostProcessor
//子类BeanDefinitionRegistryPostProcessor也扩展了BeanFactoryPostProcessor
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
// 可以先跳过:
// 循环传进来的beanFactoryPostProcessors,正常情况下,beanFactoryPostProcessors肯定没有数据
// 因为beanFactoryPostProcessors是获得手动添加的,而不是spring扫描的
// 只有手动调用annotationConfigApplicationContext.addBeanFactoryPostProcessor(XXX)才会有数据
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
//如过是BeanDefinitionRegistryPostProcessor的话,调用其方法
registryProcessor.postProcessBeanDefinitionRegistry(registry);
//添加到BeanDefinitionRegistryPostProcessor集合
registryProcessors.add(registryProcessor);
}
else {
//添加到普通的集合,非BeanDefinitionRegistryPostProcessor实现的子类
regularPostProcessors.add(postProcessor);
}
}
//一个临时变量,用来装载子类BeanDefinitionRegistryPostProcessor
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// 3.调用所有实现PriorityOrdered接口的BeanDefinitionRegistryPostProcessor实现类
// 3.1 先找出所有实现BeanDefinitionRegistryPostProcessor接口的Bean的beanName
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
// 3.2 遍历postProcessorNames,进行过滤
for (String ppName : postProcessorNames) {
// 3.3 校验是否实现了PriorityOrdered接口
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
// 3.4 获取ppName对应的bean实例, 添加到currentRegistryProcessors中
//其实就是内置的bean的名称org.springframework.context.annotation.internalConfigurationAnnotationProcessor
// beanFactory.getBean(): 这边getBean方法会触发创建ppName对应的bean对象, 目前暂不深入解析
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
//3.5 将要被执行的加入processedBeans,避免后续重复执行
processedBeans.add(ppName);
}
}
// 3.6 进行排序(根据是否实现PriorityOrdered、Ordered接口和order值来排序)
sortPostProcessors(currentRegistryProcessors, beanFactory);
//3.7 合并Processors,为什么要合并,因为registryProcessors是装载BeanDefinitionRegistryPostProcessor的
//一开始的时候,spring只会执行子类BeanDefinitionRegistryPostProcessor独有的方法
//而不会执行BeanDefinitionRegistryPostProcessor父类的方法,即BeanFactoryProcessor的方法
//所以这里需要把处理器放入一个集合中,后续统一执行父类的方法
registryProcessors.addAll(currentRegistryProcessors);
//3.8 遍历currentRegistryProcessors, 执行子类BeanDefinitionRegistryPostProcessor独有的方法postProcessBeanDefinitionRegistry()方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
// 3.9 执行完毕后,清空临时变量
currentRegistryProcessors.clear();
// 4.调用所有实现了Ordered接口的BeanDefinitionRegistryPostProcessor实现类(过程跟上面的步骤3基本一样)
// 4.1 先找出所有实现BeanDefinitionRegistryPostProcessor接口的类, 这边重复查找是因为执行完上面的BeanDefinitionRegistryPostProcessor,
// 可能会新增了其他的BeanDefinitionRegistryPostProcessor, 因此需要重新查找
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
//校验是否实现了Ordered接口,与步骤3相比,有个细微区别,就是!processedBeans.contains(ppName)避免重复步骤3已经处理过的
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
//也是实例化bean
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
// 4.2 遍历currentRegistryProcessors,此时是执行我们自定义的子类BeanDefinitionRegistryPostProcessor的特有方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
//清空临时变量
currentRegistryProcessors.clear();
//5.最后, 调用所有剩下的子类BeanDefinitionRegistryPostProcessors
//子类中那些没有同时实现PriorityOrdered接口(步骤3处理的)、或Orderer接口(步骤4处理的)的,
boolean reiterate = true;
while (reiterate) {
reiterate = false;
// 5.1 找出所有实现BeanDefinitionRegistryPostProcessor接口的类
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
// 5.2 注意:避免处理已经处理过的
if (!processedBeans.contains(ppName)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
// 5.3 如果有BeanDefinitionRegistryPostProcessor被执行, 则有可能会产生新的BeanDefinitionRegistryPostProcessor,
// 因此这边将reiterate赋值为true, 代表需要再循环查找一次
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
}
//6.上面的代码是执行子类独有的方法,这里需要再把父类BeanFactoryPostProcessor的方法也执行一次
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
//7. 最后, 调用入参beanFactoryPostProcessors中的普通BeanFactoryPostProcessor的postProcessBeanFactory方法
//一般情况下,是不会有数据的
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
else {
// Invoke factory processors registered with the context instance.
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
//------------------------
//到这里 , 入参beanFactoryPostProcessors和容器中的所有子类BeanDefinitionRegistryPostProcessor已经全部处理完毕,
// 下面开始处理容器中的所有BeanFactoryPostProcessor
// [8].找出所有实现BeanFactoryPostProcessor接口的类
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// 用于存放实现了PriorityOrdered接口的BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
// 用于存放实现了Ordered接口的BeanFactoryPostProcessor的beanName
List<String> orderedPostProcessorNames = new ArrayList<>();
// 用于存放普通BeanFactoryPostProcessor的beanName(除去实现了PriorityOrdered接口和实现了Ordered接口之后剩下的)
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
// 8.1 遍历postProcessorNames, 将BeanFactoryPostProcessor按实现PriorityOrdered、实现Ordered接口、普通三种区分开
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
// 8.2 跳过已经执行过的
}
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
// 8.3 添加实现了PriorityOrdered接口的BeanFactoryPostProcessor,
// 注意与8.4的区别,这里存储的是实例化后的bean
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
// 8.4 添加实现了Ordered接口的BeanFactoryPostProcessor的beanName
// 注意与8.3区别,这里存储的是尚未实例化的beanName
orderedPostProcessorNames.add(ppName);
}
else {
// 8.5 添加剩下的普通BeanFactoryPostProcessor的beanName
nonOrderedPostProcessorNames.add(ppName);
}
}
// 9.调用所有实现PriorityOrdered接口的BeanFactoryPostProcessor
// 9.1 对priorityOrderedPostProcessors排序
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
// 9.2 遍历priorityOrderedPostProcessors, 执行postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// 10.调用所有实现Ordered接口的BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String postProcessorName : orderedPostProcessorNames) {
// 10.1 获取postProcessorName对应的bean实例, 添加到orderedPostProcessors, 准备执行
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
// 10.2 对orderedPostProcessors排序
sortPostProcessors(orderedPostProcessors, beanFactory);
// 10.3 遍历orderedPostProcessors, 执行postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// 11.调用所有剩下的BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String postProcessorName : nonOrderedPostProcessorNames) {
// 11.1 获取postProcessorName对应的bean实例, 添加到nonOrderedPostProcessors, 准备执行
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
// 11.2 遍历nonOrderedPostProcessors, 执行postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
// 12.清除元数据缓存(mergedBeanDefinitions、allBeanNamesByType、singletonBeanNamesByType),
// 因为后处理器可能已经修改了原始元数据,例如, 替换值中的占位符...
beanFactory.clearMetadataCache();
}
1.2.1 注释[1]
判断 beanFactory 是否为 BeanDefinitionRegistry。beanFactory 是在之前的 obtainFreshBeanFactory 方法构建的,具体代码在:AbstractRefreshableApplicationContext.refreshBeanFactory() 方法,代码如下。
@Override
protected final void refreshBeanFactory() throws BeansException {
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
// 创建一个新的BeanFactory
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
customizeBeanFactory(beanFactory);
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
可以看出,我们构建的 beanFactory 是一个 DefaultListableBeanFactory ,而 DefaultListableBeanFactory 实现了BeanDefinitionRegistry 接口,因此 beanFactory instanceof BeanDefinitionRegistry 结果为 true。
1.2.2 注释[3]
调用如下方法,查找已经注册过的BeanDefinitionRegistryPostProcessor类型的bean:
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
这个bean是在哪注册的?
其实是提前注册的!
参见《spring源码》中<1.1.1.2 实例化建BeanDefinition读取器: AnnotatedBeanDefinitionReader>章节提到的知识,利用AnnotatedBeanDefinitionReader注册的内置的几个bean,其中的bean的名称org.springframework.context.annotation.
internalConfigurationAnnotationProcessor
,class="ConfigurationClassPostProcessor
",这个类是BeanDefinitionRegistryPostProcessor的子类
1.2.2.1 注释[3.4]
获取 ppName 对应的 bean 实例,添加到 currentRegistryProcessors 中,准备执行。beanFactory.getBean()
方法会触发创建 ppName 对应的 bean 实例对象,创建 bean 实例是 IoC 的另一个核心内容,之后会单独解析,目前暂不深入解析。
1.2.2.2 注释[3.8]
遍历currentRegistryProcessors, 执行子类BeanDefinitionRegistryPostProcessor独有的方法postProcessBeanDefinitionRegistry()方法,这里实际是执行孙子类ConfigurationClassPostProcessor
究竟做了啥?这个类负责解析JavaConfig类,根据“@ComponentScan(basePackages = {"com.test.spring"})”
定义的路径,扫描该路径下的所有带@Component @service等标签的类,并将它们的BeanDefinition全部注册。
我们看下console日志:
日志显示,我们定义的bean,包括car,MyBeanFactoryPostProcessor,MyBeanPostProcessor均被扫描注册了。
1.2.3 注释[6]
进行排序,该方法在下面也被调用了好几次,见代码块3详解。
1.2.4 注释[8]
自定义的myBeanFactoryPostProcessor
终于被注册了
1.3 代码块3:sortPostProcessors()
private static void sortPostProcessors(List<?> postProcessors, ConfigurableListableBeanFactory beanFactory) {
Comparator<Object> comparatorToUse = null;
if (beanFactory instanceof DefaultListableBeanFactory) {
// 1.获取设置的比较器
comparatorToUse = ((DefaultListableBeanFactory) beanFactory).getDependencyComparator();
}
if (comparatorToUse == null) {
// 2.如果没有设置比较器, 则使用默认的OrderComparator
comparatorToUse = OrderComparator.INSTANCE;
}
// 3.使用比较器对postProcessors进行排序
Collections.sort(postProcessors, comparatorToUse);
}
默认情况下,比较器为 OrderComparator;如果配置了 annotation-config,并且值为true,使用的是 AnnotationAwareOrderComparator(《Spring IoC:context:component-scan节点解析》 代码块17中设置了dependencyComparator 属性为 AnnotationAwareOrderComparator.INSTANCE),AnnotationAwareOrderComparator 继承自 OrderComparator,只是重写了部分方法,比较器的部分代码如下:
@Override
public int compare(Object o1, Object o2) {
return doCompare(o1, o2, null);
}
private int doCompare(Object o1, Object o2, OrderSourceProvider sourceProvider) {
// 判断o1是否实现了PriorityOrdered接口
boolean p1 = (o1 instanceof PriorityOrdered);
// 判断o2是否实现了PriorityOrdered接口
boolean p2 = (o2 instanceof PriorityOrdered);
// 1.如果o1实现了PriorityOrdered接口, 而o2没有, 则o1排前面
if (p1 && !p2) {
return -1;
}
// 2.如果o2实现了PriorityOrdered接口, 而o1没有, 则o2排前面
else if (p2 && !p1) {
return 1;
}
// 3.如果o1和o2都实现(都没实现)PriorityOrdered接口
// Direct evaluation instead of Integer.compareTo to avoid unnecessary object creation.
// 拿到o1的order值, 如果没实现Ordered接口, 值为Ordered.LOWEST_PRECEDENCE
int i1 = getOrder(o1, sourceProvider);
// 拿到o2的order值, 如果没实现Ordered接口, 值为Ordered.LOWEST_PRECEDENCE
int i2 = getOrder(o2, sourceProvider);
// 4.通过order值(order值越小, 优先级越高)排序
return (i1 < i2) ? -1 : (i1 > i2) ? 1 : 0;
}
比较器的逻辑很简单,实现 PriorityOrdered 接口的优先级最高,如果两个对象都实现(都没实现)PriorityOrdered 接口,则根据 order 值(实现 Ordered 接口时,需要实现 getOrder() 方法,返回 order 值)来进行比较,order 值越小,优先级越高。
3. 扩展知识
3.1 BeanDefinitionRegistryPostProcessor 的扩展使用
使用方法比较简单,新建一个类实现 BeanDefinitionRegistryPostProcessor 接口,并将该类注册到 Spring IoC 容器中。
package com.joonwhee.open.demo.spring;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
/**
* @author joonwhee
* @date 2019/2/18
*/
@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor, Ordered {
//BeanDefinitionRegistryPostProcessor接口定义的抽象方法
//一般用来完成bean的注册功能
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
System.out.println("MyBeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry");
// 自己的逻辑处理
}
//爷爷接口,BeanFactoryPostProcessor定义的
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("MyBeanDefinitionRegistryPostProcessor#postProcessBeanFactory");
// 自己的逻辑处理
}
@Override
public int getOrder() {
return 0;
}
}
具体的使用场景,需要读者自己去探讨,这边给一个常见的使用例子。
例子:
我们通常在使用 Mybatis + Spring
时,经常用到的 org.mybatis.spring.mapper.MapperScannerConfigurer
就是一个BeanDefinitionRegistryPostProcessor
。MapperScannerConfigurer 在 postProcessBeanDefinitionRegistry()
方法中进行了一些操作,主要是:
扫描 basePackage 指定的目录,将该目录下的类(通常是 DAO/MAPPER 接口)封装成 BeanDefinition 并加载到 BeanFactory 中。
因此,我们可以看到我们项目中的 DAO(MAPPER)接口,通常都没有使用注解或 XML 的方式注册到 Spring 容器,但是我们还是可以在 Service 服务中,使用 @Autowire 注解来将其注入到 Service 中,就是因为这个原因。
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!--basePackage指定要扫描的包,在此包之下的映射器都会被搜索到。可指定多个包,包与包之间用逗号或分号分隔-->
<property name="basePackage" value="com.joonwhee.open.demo.mapper"/>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>
MapperScannerConfigurer.java:
3.2. BeanFactoryPostProcessor 接口的扩展使用
使用方法跟 BeanDefinitionRegistryPostProcessor 类似,且是BeanDefinitionRegistryPostProcessor的父接口,执行优先级低一些。
package com.joonwhee.open.demo.spring;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;
/**
* @author joonwhee
* @date 2019/2/18
*/
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("MyBeanFactoryPostProcessor#postProcessBeanFactory");
// 自己的逻辑处理
}
}
4. 总结
invokeBeanFactoryPostProcessors 方法的内容其实比较少,大部分过程在代码块2的注释都已经写清楚,这边在稍微总结一下。
1.整个 invokeBeanFactoryPostProcessors 方法围绕两个接口,BeanDefinitionRegistryPostProcessor 和 BeanFactoryPostProcessor,其中 BeanDefinitionRegistryPostProcessor 继承了 BeanFactoryPostProcessor 。BeanDefinitionRegistryPostProcessor 主要用来在常规 BeanFactoryPostProcessor 检测开始之前注册其他 Bean 定义,说的简单点,就是 BeanDefinitionRegistryPostProcessor 具有更高的优先级,执行顺序在 BeanFactoryPostProcessor 之前。
2.整个 invokeBeanFactoryPostProcessors 方法操作了 3 种 bean 对象:
-
入参 beanFactoryPostProcessors:这个我们在代码块1中解析过,拿的是 AbstractApplicationContext 类的 beanFactoryPostProcessors 属性值,也就是在之前已经添加到 beanFactoryPostProcessors 中的 BeanFactoryPostProcessor。
一般情况下为空,除非手动(额外配置)添加进去
-
BeanDefinitionRegistryPostProcessor 接口实现类:实现了 BeanDefinitionRegistryPostProcessor 接口,并且注册到 Spring IoC容器中。
-
常规 BeanFactoryPostProcessor 接口实现类:实现了 BeanFactoryPostProcessor 接口,并且注册到 Spring IoC容器中。
3.操作3种 bean 对象具体指的是调用它们重写的方法,调用实现方法时会遵循以下的优先级:
- 第一优先级:入参 beanFactoryPostProcessors 中的 BeanDefinitionRegistryPostProcessor, 调用 postProcessBeanDefinitionRegistry 方法(2.1.1)。
- 第二优先级:BeanDefinitionRegistryPostProcessor 接口实现类,并且实现了
PriorityOrdered
接口,调用 postProcessBeanDefinitionRegistry 方法(3.8)。 - 第三优先级:BeanDefinitionRegistryPostProcessor 接口实现类,并且实现了
Ordered
接口,调用 postProcessBeanDefinitionRegistry 方法(4.2)。 - 第四优先级:除去第二优先级和第三优先级,剩余的 BeanDefinitionRegistryPostProcessor 接口实现类,调用 postProcessBeanDefinitionRegistry 方法(5.4)。
- 第五优先级:所有 BeanDefinitionRegistryPostProcessor 接口实现类,调用 postProcessBeanFactory 方法(6)。
- 第六优先级:入参 beanFactoryPostProcessors 中的常规 BeanFactoryPostProcessor,调用 postProcessBeanFactory 方法(7)。
- 第七优先级:常规 BeanFactoryPostProcessor 接口实现类,并且实现了
PriorityOrdered
接口,调用 postProcessBeanFactory 方法(9.2)。 - 第八优先级:常规 BeanFactoryPostProcessor 接口实现类,并且实现了
Ordered
接口,调用 postProcessBeanFactory 方法(10.3)。 - 第九优先级:除去第七优先级和第八优先级,剩余的常规 BeanFactoryPostProcessor 接口的实现类,调用 postProcessBeanFactory 方法(11.2)。
4.本文还引入了两个用于排序的重要接口:PriorityOrdered 和 Ordered,其中 PriorityOrdered 继承了 Ordered,并且 PriorityOrdered 的优先级要高于 Ordered,这跟 BeanDefinitionRegistryPostProcessor 继承 BeanFactoryPostProcessor 有点类似。实现 Ordered 接口需要重写 getOrder 方法,返回一个用于排序的 order 值,order 值的范围为 Integer.MIN_VALUE ~ Integer.MAX_VALUE,order 值越小优先级越高,Integer.MIN_VALUE 拥有最高优先级,而 Integer.MAX_VALUE 则对应的拥有最低优先级。
5.常见的 Java EE 相关的框架或者中间件,经常使用 BeanFactoryPostProcessor 来进行扩展,例如上面的 Mybatis,因此了解 BeanFactoryPostProcessor 的原理会对之后理解其他中间件的原理有帮助。