这篇文章主要记录下BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor的学习和一些见解;
我习惯先说结论,然后再细说具体的源码:
在spring源码中,这两个接口的实现类完成了bean的扫描和对配置类生成了代理对象
我们以 ***ConfigurationClassPostProcessor***这个类为例,来学习这两个接口;
说到这个类,我们要说的源码是这个方法:
org.springframework.context.support.AbstractApplicationContext#invokeBeanFactoryPostProcessors
在源码中,BeanFactoryPostProcessor的接口中定义的方法是void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
BeanDefinitionRegistryPostProcessor定义的方法是void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException; 这两个接口都是spring提供的扩展点,执行时机是在bean实例化之前;
我们在前面的源码解析中 spring源码-bean加载整体流程 文章中有提到过,在spring初始化的源码中,需要特别注意一下ConfigurationClassPostProcessor这个类,因为这个类在spring自动扫描bean起到了非常大的作用
invokeBeanFactoryPostProcessors(beanFactory);方法会调用到下面的这个方法,这个方法就是本篇的核心
/**
* @param beanFactory
* @param beanFactoryPostProcessors
*
* 这里是对beanDefinitionRegistryPostProcessor和beanFactoryPostProcessor实现类的出来
* 1.先执行程序员通过API提供的beanDefinitionRegistryPostProcessor的实现类
* 2.执行spring中,实现了PriorityOrdered接口且实现了beanDefinitionRegistryPostProcessor接口的实现类
* 3.执行spring中,实现了Ordered接口且实现了beanDefinitionRegistryPostProcessor接口的实现类
* 4.执行spring中,只实现了beanDefinitionRegistryPostProcessor接口的实现类
* 5.执行实现了beanFactoryPostProcessor接口的实现类
*/
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// Invoke BeanDefinitionRegistryPostProcessors first, if any.
//这个set集合可以理解为存储的是已经执行过的beanDefinitionRegistryPostProcessor
Set<String> processedBeans = new HashSet<>();
/**
* 这里之所以要判断beanFactory是哪种类型的,应该和org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry(org.springframework.beans.factory.support.BeanDefinitionRegistry)
* 的入参有关系
*/
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
//regularPostProcessors这个list存储的是beanFactoryPostProcessor接口的实现类
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
//registryProcessors 这个list存储的是beanDefinitionRegistryPostProcessor接口的实现类
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
/**
* 序号1
* 这里的beanFactoryPostProcessors是程序员自己提供的BeanFactoryPostProcessor的实现类
*/
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
/**
* 区分当前bean是BeanDefinitionRegistryPostProcessor还是 beanFactoryPostProcessor
* 因为前者是后者的子类,所以在获取beanFactoryPostprocessor的时候 也可以获取到
*
* 在本方法中 是先执行实现了BeanDefinitionRegistryPostProcessor的类
* 再执行beanFactoryPostProcessor的类
* 序号1.1
*/
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
//这里直接执行程序员通过API注入的beanDefinitionRegistryPostProcessor的实现类
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
else {
// 序号1.2 将beanFactoryPostProcessor添加到regularPostProcessors
regularPostProcessors.add(postProcessor);
}
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
// Separate between BeanDefinitionRegistryPostProcessors that implement
// PriorityOrdered, Ordered, and the rest.
//这里的这个list是用来存放spring中实现了beanFactoryRegistryPostProcessor接口的实现类
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
/**
* 序号2
*获取到了一个BeanDefinitionRegistryPostProcessor的实现类 -- ConfigurationClassPostprocessor
* 并且这里也只会获取到一个,因为截止到目前,spring容器中还没有我们自己写的业务类,只有spring自己注入的集合bean;
* 而这几个bean中,只有ConfigurationClassPostProcessor是BeanDefinitionRegistryPostProcessor的实现类
*
* 需要注意的是:
* 这个类在spring解析扫描初始化的时候用到了,ConfigurationClassPostProcessor是最重要的一个
*
* 在这里获取beanDefinitionRegistryPostProcessor类型的bean的时候,会对bean一个合并,也就是所谓的mergeBean
* 在后面finishBeanFactoryInitialization方法中,对bean进行实例化的时候,会再判断一次
*/
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
/**
* 序号3
* spring内部在执行BeanDefinitionRegistryPostProcessor的实现类的时候,是由顺序的
* 实现了PriorityOrdered接口的类 --> 实现了Ordered接口的类 --> other
*
*/
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
//排序,合并spring自己的和程序员自定义的beanFactoryRegistryPostProcessor
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
/**
* 序号3.1
* invokeBeanDefinitionRegistryPostProcessors这行代码,在本方法中调用了三次
* 这里是第一次调用,这是,理论上只有一个,就是ConfigurationClassPostProcessor
*
*/
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
/**
* 可以看到,在第二次和第三次从容器中获取实现类的时候,会先从已经执行过的集合中进行过滤(processedBeans)过滤
*/
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
/**
* 序号3.2
* 这里是第二次调用,执行实现了Ordered接口的类
*/
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
/**
* 序号3.3
* 这里执行的是所有实现了beanDefinitionRegistryPostProcessor且无实现其他接口的类
*
* 这里为什么要用while(true)?
* 因为有可能beanDefinitionRegistryPostProcessor的实现类中有可能会又注入了一个beanDefinitionRegistryPostProcessor的实现类,所以这里要循环查找并执行;
* 如果第二次从beanFactory中没有找到beanDefinitionRegistryPostProcessor的实现类,那么,这里reiterate就是false,就不会再执行了
* 如果第二次从beanFactory中找到了未执行的实现类,那么就会继续执行,同时,reiterate变为true;然后进行下一轮的循环
*/
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();
}
// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
/**
* 序号4
* 前面说了,registryProcessors是保存beanDefinitionRegistryPostProcessor接口的实现类
* regularPostProcessors保存的是程序员提供的beanFactoryPostProcessor接口的实现类,
* 那为什么这里还会有 invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);这行代码?
* 原因很简单,一个接口在实现beanDefinitionRegistryPostProcessor接口的同时,必然会实现beanFactoryPostProcessor接口
* 所以,这里要执行
* registryProcessors中是spring内置的beanFactoryPostProcessor
* regularPostProcessors是程序员提供的beanFactoryPostProcessor
*
* 所以,spring源码中,
* 1.会先执行程序员提供的BeanDefinitionRegistryPostProcessor接口的实现类,
* 2.会执行spring自带的 BeanDefinitionRegistryPostProcessor接口的实现类
* 3.然后执行spring自带的 BeanDefinitionRegistryPostProcessor接口的实现类中的postProcessBeanFactory方法
* 4.最后执行程序员提供的 BeanDefinitionRegistryPostProcessor接口的实现类中的postProcessBeanFactory方法
*/
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
else {
// Invoke factory processors registered with the context instance.
/**
* 如果beanFactory不是BeanDefinitionRegistry类型,就执行BeanFactoryPostProcessor的实现类
*/
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
/**
* 这里的是程序员提供的beanFactoryPostProcessor的实现类,是通过@Component注解提供的,而不是ac.addBeanFactoryPostProcessor提供的
*
* 上面执行的,仅仅是程序员通过add到spring容器中的beanFactoryPostProcessor
*
* 在对包进行扫描的时候,会把我们定义的通过@Component注入的beanFactoryPostProcessor的实现类,作为beanDefinition注入,然后在这里进行处理:也即:当spring执行到这里的时候,已经将bean转换成了beanDefinition,且存到了BeanDefinitionMaps中
*/
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
/**
* BeanFactoryPostProcess的实现类,在执行的时候,也是有优先级的
* PriorityOrdered --> Ordered --> other
*/
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
//如果当前beanFactoryPostProcessor已经被执行过了,就跳过,无需再次执行
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
}
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);
}
}
// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// Finally, invoke all other BeanFactoryPostProcessors.
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
// Clear cached merged bean definitions since the post-processors might have
// modified the original metadata, e.g. replacing placeholders in values...
beanFactory.clearMetadataCache();
}
方法里面的注释我分别标上了序号,其中,在序号3.1这里的invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry)
方法中,完成了对@ComponeneScan注解的处理,将包中添加了@Component注解的业务类解析成BeanDefinition,存入到BeanDefinitionMap中
本身而言,BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor是spring的扩展点;
如果我们自己声明一个类,实现了BeanFactoryPostProcessor接口,那我们可以在实现类中,获取到beanFactory对象,可以对所有的beanDefinition进行操作(因为在spring源码中,会先执行spring字段的ConfigurationClassPostProcessor,完成bean的扫描,并将bean转换为beanDefinition,存入到beanDefinitionMap中);但是这个扩展点的执行时机,太早了,我觉得一般的业务代码,可能不怎么会用到的这个扩展点。