参考资料
《Spring IoC源码学习:invokeBeanFactoryPostProcessors 详解》
前文:
《Spring IOC:obtainFreshBeanFactory调用链》
写在开头:本文为个人学习笔记,内容比较随意,夹杂个人理解,如有错误,欢迎指正。
目录
二、invokeBeanFactoryPostProcessors
1、getBeanFactoryPostProcessors
2、invokeBeanFactoryPostProcessors
三、getBeanFactoryPostProcessors
1、getBeanFactoryPostProcessors
2、添加自定义BeanFactoryPostProcessor
三、invokeBeanFactoryPostProcessors
1、区分BeanDefinitionRegistryPostProcessor与BeanFactoryPostProcessor
2、根据优先级实现BeanDefinitionRegistryPostProcessor
3、实例化剩余BeanDefinitionRegistryPostProcessors与部分BeanFactoryPostProcessor
4、针对BeanFactoryPostProcessor重复2、3步操作
一、概述
invokeBeanFactoryPostProcessors方法会实例化和调用所有 BeanFactoryPostProcessor(包括其子类 BeanDefinitionRegistryPostProcessor)。
BeanFactoryPostProcessor 接口是 Spring 初始化 BeanFactory 时对外暴露的扩展点,Spring IoC 容器允许 BeanFactoryPostProcessor 在容器实例化任何 bean 之前读取 bean 的定义,并可以修改它。
二、invokeBeanFactoryPostProcessors
2个重要步骤:
1、getBeanFactoryPostProcessors
拿到当前应用上下文beanFactoryPostProcessors变量中的值
2、invokeBeanFactoryPostProcessors
实例化并调用所有已注册的BeanFactoryPostProcessor
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
// getBeanFactoryPostProcessors(): 拿到当前应用上下文beanFactoryPostProcessors变量中的值
// invokeBeanFactoryPostProcessors: 实例化并调用所有已注册的BeanFactoryPostProcessor
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
三、getBeanFactoryPostProcessors
1、getBeanFactoryPostProcessors
拿到当前应用上下文中已经注册的 BeanFactoryPostProcessor,默认情况下返回为空。
public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() {
return this.beanFactoryPostProcessors;
}
2、添加自定义BeanFactoryPostProcessor
在《Spring IOC:从ContextLoaderListener到AbstractApplicationContext》中介绍的customizeContext方法会通过determineContextInitializerClasses方法读取web.xml中的参数(globalInitializerClasses与contextInitializerClasses),初始化实现了ApplicationContextInitializer接口的类。
protected void customizeContext(ServletContext sc, ConfigurableWebApplicationContext wac) {
//获取初始化器类集合
List<Class<ApplicationContextInitializer<ConfigurableApplicationContext>>> initializerClasses =
determineContextInitializerClasses(sc);
for (Class<ApplicationContextInitializer<ConfigurableApplicationContext>> initializerClass : initializerClasses) {
Class<?> initializerContextClass =
GenericTypeResolver.resolveTypeArgument(initializerClass, ApplicationContextInitializer.class);
if (initializerContextClass != null && !initializerContextClass.isInstance(wac)) {
throw new ApplicationContextException(String.format(
"Could not apply context initializer [%s] since its generic parameter [%s] " +
"is not assignable from the type of application context used by this " +
"context loader: [%s]", initializerClass.getName(), initializerContextClass.getName(),
wac.getClass().getName()));
}
//实例化初始化器并添加到集合中
this.contextInitializers.add(BeanUtils.instantiateClass(initializerClass));
}
//排序并执行,编号越小越早执行
AnnotationAwareOrderComparator.sort(this.contextInitializers);
for (ApplicationContextInitializer<ConfigurableApplicationContext> initializer : this.contextInitializers) {
initializer.initialize(wac);
}
}
protected List<Class<ApplicationContextInitializer<ConfigurableApplicationContext>>>
determineContextInitializerClasses(ServletContext servletContext) {
List<Class<ApplicationContextInitializer<ConfigurableApplicationContext>>> classes =
new ArrayList<Class<ApplicationContextInitializer<ConfigurableApplicationContext>>>();
//通过<context-param>属性配置globalInitializerClasses获取全局初始化类名
String globalClassNames = servletContext.getInitParameter(GLOBAL_INITIALIZER_CLASSES_PARAM);
if (globalClassNames != null) {
for (String className : StringUtils.tokenizeToStringArray(globalClassNames, INIT_PARAM_DELIMITERS)) {
classes.add(loadInitializerClass(className));
}
}
//通过<context-param>属性配置contextInitializerClasses获取容器初始化类名
String localClassNames = servletContext.getInitParameter(CONTEXT_INITIALIZER_CLASSES_PARAM);
if (localClassNames != null) {
for (String className : StringUtils.tokenizeToStringArray(localClassNames, INIT_PARAM_DELIMITERS)) {
classes.add(loadInitializerClass(className));
}
}
return classes;
}
@SuppressWarnings("unchecked")
private Class<ApplicationContextInitializer<ConfigurableApplicationContext>> loadInitializerClass(String className) {
try {
// 实例化className
Class<?> clazz = ClassUtils.forName(className, ClassUtils.getDefaultClassLoader());
if (!ApplicationContextInitializer.class.isAssignableFrom(clazz)) {
// 校验clazz是否实现了ApplicationContextInitializer接口, 如果没有则抛异常
throw new ApplicationContextException(
"Initializer class does not implement ApplicationContextInitializer interface: " + clazz);
}
// clazz强转成ApplicationContextInitializer, 并返回
return (Class<ApplicationContextInitializer<ConfigurableApplicationContext>>) clazz;
} catch (ClassNotFoundException ex) {
throw new ApplicationContextException("Failed to load context initializer class [" + className + "]", ex);
}
}
我们通过新建一个ApplicationContextInitializer的实现类并重写initialize方法实现个性化逻辑,在其中手动添加继承了BeanFactoryPostProcessor接口的MyBeanFactoryPostProcessor。并通过globalInitializerClasses将其注册到上下文中,就可以实现beanFactoryPostProcessors的预存功能。
public class MyApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext>
{
public void initialize(ConfigurableApplicationContext applicationContext) {
MyBeanFactoryPostProcessor myBeanFactoryPostProcessor = new MyBeanFactoryPostProcessor();
applicationContext.addBeanFactoryPostProcessor(myBeanFactoryPostProcessor);
System.out.println("将自定义的MyBeanFactoryPostProcessor添加到应用上下文中");
}
}
<context-param>
<param-name>globalInitializerClasses</param-name>
<param-value>
com.test.MyApplicationContextInitializer
</param-value>
</context-param>
三、invokeBeanFactoryPostProcessors
首先要介绍下BeanFactoryPostProcessor及其子类BeanDefinitionRegistryPostProcessor。
BeanFactoryPostProcessor 接口是 Spring 初始化 BeanFactory 时对外暴露的扩展点,Spring IoC 容器允许 BeanFactoryPostProcessor 在容器实例化任何 bean 之前读取 bean 的定义,并可以修改它。
BeanDefinitionRegistryPostProcessor继承自BeanFactoryPostProcessor,比 BeanFactoryPostProcessor 具有更高的优先级,主要用来在常规的BeanFactoryPostProcessor 检测开始之前执行。特别是,你可以通过BeanDefinitionRegistryPostProcessor来注册一些常规的BeanFactoryPostProcessor。因为此时所有常规的 BeanFactoryPostProcessor都还没开始被处理。
对于BeanFactoryPostProcessor的介绍可以看我之前写的文章《传送门》
由于invokeBeanFactoryPostProcessors整段代码较长,这里按照执行步骤拆分成了几段,如下图所示。
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
1、区分BeanDefinitionRegistryPostProcessor与BeanFactoryPostProcessor
2、根据优先级实现BeanDefinitionRegistryPostProcessor
3、实例化剩余BeanDefinitionRegistryPostProcessors与部分BeanFactoryPostProcessor
4、针对BeanFactoryPostProcessor重复2、3步操作
}
1、区分BeanDefinitionRegistryPostProcessor与BeanFactoryPostProcessor
遍历入参beanFactoryPostProcessors,并区分开BeanDefinitionRegistryPostProcessor与BeanFactoryPostProcessor,前者比后者多一步直接执行其postProcessBeanDefinitionRegistry方法,然后分别存入registryProcessors 与regularPostProcessors中。
注意:这里存储和实现的是作为参数传的beanFactoryPostProcessors,即我们在前文中介绍的利用ApplicationContextInitializer拓展实现的BeanFactoryPostProcessor,不包括在容器中注册的BeanFactoryPostProcessor。
Set<String> processedBeans = new HashSet<String>();
// 判断beanFactory是否为BeanDefinitionRegistry,beanFactory为DefaultListableBeanFactory,
// 而DefaultListableBeanFactory实现了BeanDefinitionRegistry接口,因此这边为true
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
// 用于存放普通的BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
// 用于存放BeanDefinitionRegistryPostProcessor
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new LinkedList<BeanDefinitionRegistryPostProcessor>();
// 首先处理入参中的beanFactoryPostProcessors
// 遍历所有的beanFactoryPostProcessors, 将BeanDefinitionRegistryPostProcessor和普通BeanFactoryPostProcessor区分开
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
// 如果是BeanDefinitionRegistryPostProcessor
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
// 直接执行BeanDefinitionRegistryPostProcessor接口的postProcessBeanDefinitionRegistry方法
registryProcessor.postProcessBeanDefinitionRegistry(registry);
// 添加到registryProcessors(用于最后执行postProcessBeanFactory方法)
registryProcessors.add(registryProcessor);
} else {
// 否则,只是普通的BeanFactoryPostProcessor
// 添加到regularPostProcessors(用于最后执行postProcessBeanFactory方法)
regularPostProcessors.add(postProcessor);
}
}
2、根据优先级实现BeanDefinitionRegistryPostProcessor
(1)找出所有实现BeanDefinitionRegistryPostProcessor接口的Bean的beanName,存入postProcessorNames中(这里beanName是通过beanFactory.getBeanNamesForType从前一步obtainFreshBeanFactory方法中注册的beanName中找出的)
(2)遍历postProcessorNames,过滤出实现了PriorityOrdered接口(排序用)的beanName。
(3)使用beanFactory.getBean方法创建该BeanDefinitionRegistryPostProcessor对应的bean对象。将创建完成的bean对象存入currentRegistryProcessors,并将该beanName存入processedBeans。
(4)根据PriorityOrdered接口的实现情况对currentRegistryProcessors排序,然后将currentRegistryProcessors存入registryProcessors中。
(5)遍历currentRegistryProcessors, 执行postProcessBeanDefinitionRegistry方法。执行完毕后, 清空currentRegistryProcessors。
(6)重复1-5步的过程,但会重新获取postProcessorNames,这是因为执行完上面的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法,可能会新增了其他的BeanDefinitionRegistryPostProcessor, 因此需要重新查找。且这一步针对的是Ordered接口而不是PriorityOrdered接口。
// 用于保存本次要执行的BeanDefinitionRegistryPostProcessor
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
// 调用所有实现PriorityOrdered接口的BeanDefinitionRegistryPostProcessor实现类
// 找出所有实现BeanDefinitionRegistryPostProcessor接口的Bean的beanName
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
// 遍历postProcessorNames
for (String ppName : postProcessorNames) {
// 校验是否实现了PriorityOrdered接口
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
// 获取ppName对应的bean实例, 添加到currentRegistryProcessors中,
// beanFactory.getBean: 这边getBean方法会触发创建ppName对应的bean对象, 目前暂不深入解析
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
// 将要被执行的加入processedBeans,避免后续重复执行
processedBeans.add(ppName);
}
}
// 进行排序(根据是否实现PriorityOrdered、Ordered接口和order值来排序)
sortPostProcessors(currentRegistryProcessors, beanFactory);
// 添加到registryProcessors(用于最后执行postProcessBeanFactory方法)
registryProcessors.addAll(currentRegistryProcessors);
// 遍历currentRegistryProcessors, 执行postProcessBeanDefinitionRegistry方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
// 执行完毕后, 清空currentRegistryProcessors
currentRegistryProcessors.clear();
// 调用所有实现了Ordered接口的BeanDefinitionRegistryPostProcessor实现类(过程跟上面的步骤3基本一样)
// 找出所有实现BeanDefinitionRegistryPostProcessor接口的类, 这边重复查找是因为执行完上面的BeanDefinitionRegistryPostProcessor,
// 可能会新增了其他的BeanDefinitionRegistryPostProcessor, 因此需要重新查找
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.addAll(currentRegistryProcessors);
// 遍历currentRegistryProcessors, 执行postProcessBeanDefinitionRegistry方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
3、实例化剩余BeanDefinitionRegistryPostProcessors与部分BeanFactoryPostProcessor
(1)调用beanFactory.getBeanNamesForType找出所有实现BeanDefinitionRegistryPostProcessor接口的类,并跳过已经执行过的。
(2)重复上一节中3、4、5步操作。
(3)从registryProcessors中取出所有的BeanDefinitionRegistryPostProcessor,执行其postProcessBeanFactory方法。
(4)调用入参beanFactoryPostProcessors中BeanFactoryPostProcessor的postProcessBeanFactory方法。
// 最后, 调用所有剩下的BeanDefinitionRegistryPostProcessors
boolean reiterate = true;
while (reiterate) {
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);
// 如果有BeanDefinitionRegistryPostProcessor被执行, 则有可能会产生新的BeanDefinitionRegistryPostProcessor,
// 因此这边将reiterate赋值为true, 代表需要再循环查找一次
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
// 遍历currentRegistryProcessors, 执行postProcessBeanDefinitionRegistry方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
}
// 6.调用所有BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法(BeanDefinitionRegistryPostProcessor继承自BeanFactoryPostProcessor)
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
// 最后, 调用入参beanFactoryPostProcessors中的普通BeanFactoryPostProcessor的postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
} else {
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
4、针对BeanFactoryPostProcessor重复2、3步操作
前三步之后,所有的BeanDefinitionRegistryPostProcessor都已处理完毕,包括入参beanFactoryPostProcessors和容器中注册的已经全部处理完毕,下面开始处理容器中的所有BeanFactoryPostProcessor。
第4步则模仿前2步的操作,不过将BeanDefinitionRegistryPostProcessor替换为了BeanFactoryPostProcessor。
// 找出所有实现BeanFactoryPostProcessor接口的类
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// 用于存放实现了PriorityOrdered接口的BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
// 用于存放实现了Ordered接口的BeanFactoryPostProcessor的beanName
List<String> orderedPostProcessorNames = new ArrayList<String>();
// 用于存放普通BeanFactoryPostProcessor的beanName
List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
// 遍历postProcessorNames, 将BeanFactoryPostProcessor按实现PriorityOrdered、实现Ordered接口、普通三种区分开
for (String ppName : postProcessorNames) {
// 跳过已经执行过的
if (processedBeans.contains(ppName)) {
} else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
// 添加实现了PriorityOrdered接口的BeanFactoryPostProcessor
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
} else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
// 添加实现了Ordered接口的BeanFactoryPostProcessor的beanName
orderedPostProcessorNames.add(ppName);
} else {
// 添加剩下的普通BeanFactoryPostProcessor的beanName
nonOrderedPostProcessorNames.add(ppName);
}
}
// 调用所有实现PriorityOrdered接口的BeanFactoryPostProcessor
// 对priorityOrderedPostProcessors排序
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
// 遍历priorityOrderedPostProcessors, 执行postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// 调用所有实现Ordered接口的BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
for (String postProcessorName : orderedPostProcessorNames) {
// 获取postProcessorName对应的bean实例, 添加到orderedPostProcessors, 准备执行
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
// 对orderedPostProcessors排序
sortPostProcessors(orderedPostProcessors, beanFactory);
// 遍历orderedPostProcessors, 执行postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// 调用所有剩下的BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
for (String postProcessorName : nonOrderedPostProcessorNames) {
// 获取postProcessorName对应的bean实例, 添加到nonOrderedPostProcessors, 准备执行
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
// 遍历nonOrderedPostProcessors, 执行postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
// 清除元数据缓存(mergedBeanDefinitions、allBeanNamesByType、singletonBeanNamesByType),
// 因为后处理器可能已经修改了原始元数据,例如, 替换值中的占位符...
beanFactory.clearMetadataCache();
总结:
整个流程先从上下文中获取globalInitializerClasses、contextInitializerClasses参数配置的扩展点中手动添加到上下文中的BeanFactoryPostProcessor与BeanDefinitionRegistryPostProcessor。
然后将他们分开存储,并实现BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法。再获取beanFactory中注册的BeanDefinitionRegistryPostProcessor,过滤出实现了PriorityOrdered接口的beanName,排序后依次实现。同样的步骤再针对Ordered接口重复执行。最后将beanFactory中剩余的BeanDefinitionRegistryPostProcessor类型的beanName依次执行postProcessBeanDefinitionRegistry方法。最后,调用入参beanFactoryPostProcessors中的BeanFactoryPostProcessor的postProcessBeanFactory方法。
再然后,重复BeanDefinitionRegistryPostProcessor的处理过程,将对象替换为BeanFactoryPostProcessor。