前言
本文重点研究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<>();
// spring中beanFactory默认是DefaultListableBeanFactory,所以会进入此代码块
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
//装载普通的BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
//装载和Bean定义有关的 BeanDefinitionRegistryPostProcessor
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
// 这里是我们自己的set进去的,若没set,这里就是空
// 只有我们手动利用容器的addBeanFactoryPostProcessor注入BeanFactoryPostProcessor才会进入这个代码块
// 这里和我们利用注解注册的BeanFactoryPostProcessor不一样,可以忽略这段代码
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一阶段开始*********************************************/
// 调用其postProcessBeanDefinitionRegistry方法
//其实一般情况下,只会获取ConfigurationClassPostProcessor,
//因为这时候容器中只有ConfigurationClassPostProcessor这一个BeanDefinitionRegistryPostProcessor
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
//实例化和执行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循环一个个的执行掉
//其实可以狭义的理解成容器在这里解析@Configuration主配置文件
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
// 此处把当前持有的执行对象给清空了,需要注意。以方便装载后续执行的处理器们
currentRegistryProcessors.clear();
/***************************BeanDefinitionRegistryPostProcessor二阶段开始*********************************************/
//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();
/***************************BeanDefinitionRegistryPostProcessor三阶段开始*********************************************/
//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);
//我们没有手动设置,所以regularPostProcessors会一直为空,忽略此代码
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
else {
//此代码块,忽略
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
/***************************BeanFactoryPostProcessor阶段开始*********************************************/
//获取所有的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();
}
2.1 BeanDefinitionRegistryPostProcessor流程
1、从容器中获取BeanDefinitionRegistryPostProcessor,如果其是PriorityOrdered类型,那么实例化并执行其postProcessBeanDefinitionRegistry方法
延深:其实这个阶段,可以说容器中只有ConfigurationClassPostProcessor(用来解析@Configuration),他就是PriorityOrdered类型,所以在这个阶段会实例化并调用其postProcessBeanDefinitionRegistry方法
2、从容器中获取BeanDefinitionRegistryPostProcessor,如果其是Ordered类型,那么实例化并执行其postProcessBeanDefinitionRegistry方法
这个阶段可以会执行并实例化我们自己的BeanDefinitionRegistryPostProcessor,如果其是Ordered类型
3、实例化并执行上面两个排序接口都没有实现的BeanDefinitionRegistryPostProcessor,调用其postProcessBeanDefinitionRegistry
方法
这个阶段可以会执行并实例化我们自己的BeanDefinitionRegistryPostProcessor
4、先执行上面实例化过所有BeanDefinitionRegistryPostProcessor的postProcessBeanFactory
方法。
2.2 BeanFactoryPostProcessor流程
1、获取容器中所有的BeanFactoryPostProcessor,但是忽略其是BeanDefinitionRegistryPostProcessor
2、实例化并执行实现PriorityOrdered接口的BeanFactoryPostProcessor
2、实例化并执行实现Ordered接口的BeanFactoryPostProcessor
3、实例化并执行上面两个排序接口都没有实现的BeanFactoryPostProcessor