前言
本文重点研究BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor的区别和执行时机
一、方法说明
1、BeanFactoryPostProcessor
BeanFactoryPostProcessor允许使用者修改容器中的Beandefinitions
BeanFactoryPostProcessor可以与Beandefinitions打交道,但是千万不要进行bean实例化(感觉这里应该说的是不要在BeanFactoryPostProcessor进行可能触发bean实例化的操作)。这么做可能会导致bean被提前实例化,会破坏容器造成预估不到的副作用。如果你需要控制bean实例化过程,请考虑使用BeanPostProcessor
public interface BeanFactoryPostProcessor {
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
利用他,我们可以获取Beandefinition(未实例化)数据,可以随心所欲的修改属性
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("调用了自定义的BeanFactoryPostProcessor " + beanFactory);
Iterator it = beanFactory.getBeanNamesIterator();
String[] names = beanFactory.getBeanDefinitionNames();
// 获取了所有的bean名称列表
for(int i=0; i<names.length; i++){
String name = names[i];
BeanDefinition bd = beanFactory.getBeanDefinition(name);
//利用BeanDefinition方法改变当前BeanDefinition
}
}
}
2、BeanDefinitionRegistryPostProcessor
BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子接口
他和BeanFactoryPostProcessor的区别是什么?
BeanDefinitionRegistryPostProcessors表示BeanDefinitionRegistry后置处理器,可以通过实现BeanDefinitionRegistryPostProcessors接口,来向BeanDefinitionRegistry中添加BeanDefinition,并且BeanDefinitionRegistryPostProcessors本身也是一个beanFactory后置处理器。BeanDefinitionRegistryPostProcessors既可以添加BeanDefinition,也可以修改BeanDefinition。
通俗的说我们可以利用BeanDefinitionRegistryPostProcessors手动注入BeanDefinition,而BeanFactoryPostProcessor只能修改现有BeanDefinition的属性
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
}
@Configuration注解处理器
ConfigurationClassPostProcessor
就是一个BeanDefinitionRegistryPostProcessor
二、实例化并调用BeanFactoryPostProcessor
代码发生在refresh方法的invokeBeanFactoryPostProcessors(beanFactory)
模块中
final class PostProcessorRegistrationDelegate {
public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
//储存执行过的BeanFactoryPostProcessor
Set<String> processedBeans = new HashSet<>();
//只有此beanFactory 是BeanDefinitionRegistry 才能执行BeanDefinitionRegistryPostProcessor,才能修改Bean的定义嘛~
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
//装载普通的BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
//装载和Bean定义有关的 BeanDefinitionRegistryPostProcessor
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
// 这里是我们自己的set进去的,若没set,这里就是空(若是Sprng容器里的,下面会处理,见下面)
// 从此处可以看出,我们手动set进去的,最最最最有限执行的
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
// 这里执行post方法,然后然后吧它缓冲起来了,放在了registryProcessors里
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
else {
// 缓冲起来常规的处理器
regularPostProcessors.add(postProcessor);
}
}
// 接下来,就是去执行Spring容器里面的一些PostProcessor了。他们顺序doc里也写得很清楚:
// 先执行实现了PriorityOrdered接口的,然后是Ordered接口的,最后执行剩下的
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
//获取所有的BeanDefinitionRegistryPostProcessor类型BeanDefinition的名字
//如ConfigurationClassPostProcessor(@Configuration注解处理器)的名字
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
//TODO 实例化和执行PriorityOrdered类型的BeanDefinitionRegistryPostProcessor
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
// processedBeans也顺带保存了一份,保存的是bean的Name哦~
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
// 排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
// 此处缓冲起来(需要注意的是,是排序后,再放进去的 这样是最好的)
registryProcessors.addAll(currentRegistryProcessors);
// 这个方法很简单,就是吧currentRegistryProcessors里面所有的处理器for循环一个个的执行掉
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
// 此处把当前持有的执行对象给清空了,需要注意。以方便装载后续执行的处理器们
currentRegistryProcessors.clear();
//TODO 此处逻辑完全同上,实例化和执行Ordered类型的BeanDefinitionRegistryPostProcessor
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
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);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
//TODO 最后执行,实例化和执行两个排序接口都没有实现的BeanDefinitionRegistryPostProcessor们
boolean reiterate = true;
while (reiterate) {
reiterate = false;
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);
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
}
//执行上面实例化过所有BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
else {
// 若是普通的Bean工厂,就直接执行set进来的后置处理器即可(因为容器里就没有其它Bean定义了)
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
//获取所有的BeanFactoryPostProcessor类型BeanDefinition的名字
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
//存放实现PriorityOrdered接口的BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
//存放实现Ordered接口的BeanFactoryPostProcessor
List<String> orderedPostProcessorNames = new ArrayList<>();
//存放上面2个接口都没有实现的BeanFactoryPostProcessor
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
//如果当前BeanFactoryPostProcessor已经执行过了,忽略
}
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// TODO 执行实现PriorityOrdered接口的BeanFactoryPostProcessor
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// TODO Next 执行实现Ordered接口的BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// TODO Finally 执行实现剩下的BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
//清除缓存的合并bean定义,因为后处理器可能有
//修改了原始元数据,例如替换值中的占位符。。。
beanFactory.clearMetadataCache();
}
1、获取容器中所有的BeanDefinitionRegistryPostProcessor类型BeanDefinition的名字
2、实例化并执行实现PriorityOrdered接口的BeanDefinitionRegistryPostProcessor
3、实例化并执行实现Ordered接口的BeanDefinitionRegistryPostProcessor
4、实例化并执行上面两个排序接口都没有实现的BeanDefinitionRegistryPostProcessor
5、调用上述所有BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法
6、获取容器中所有的BeanFactoryPostProcessor类型BeanDefinition的名字
7、实例化并执行实现PriorityOrdered接口的BeanFactoryPostProcessor
8、实例化并执行实现Ordered接口的BeanFactoryPostProcessor
9、实例化并执行上面两个排序接口都没有实现的BeanFactoryPostProcessor