1.invokeBeanFactoryPostProcessors方法的源码
invokeBeanFactoryPostProcessors方法的代码如下
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
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 (!NativeDetector.inNativeImage() && beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
但是其真实的逻辑其实在PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors方法中。
2.关于BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor和ConfigurationClassPostProcessor之间的关系
在这个方法中会涉及到几个概念,叫BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor和ConfigurationClassPostProcessor。
2.1我们来看BeanDefinitionRegistryPostProcessor的继承关系
在PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors方法中会涉及到几个概念,叫BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor和ConfigurationClassPostProcessor。
我们来看BeanDefinitionRegistryPostProcessor的继承关系
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor
我们可以看到BeanDefinitionRegistryPostProcessor其实是BeanFactoryPostProcessor的子接口。
2.2 我们再来看一个类ConfigurationClassPostProcessor的继承关系
public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor,
PriorityOrdered, ResourceLoaderAware, ApplicationStartupAware, BeanClassLoaderAware, EnvironmentAware
我们可以看到ConfigurationClassPostProcessor实现了PriorityOrdered接口和BeanDefinitionRegistryPostProcessor接口。
3.PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors
第一行代码是一个HashSet,名叫processedBeans,顾名思义,就是用来保存已经处理过的Bean(BeanFactoryPostProcessor)的Name。在后面的代码中可以用来避免PostProcessor的Bean被重复调用,每次添加到对应的列表中,都会先判断是否已经在这个Set中。
Set<String> processedBeans = new HashSet<>();
接着是这样的代码,想要拿到BeanDefinitionRegistryPostProcessor的实现类。
//判断beanFactory是否是BeanDefinitionRegistry的实例
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
如果BeanFactory是BeanDefinitionRegistry的实例,就将BeanFactory转换成BeanDefinitionRegistry。
接着,是两个List,regularPostProcessors用来保存普通的BeanFactoryPostProcessor的实现类(Bean),registryProcessors则是保存BeanDefinitionRegistryPostProcessor的实现类(Bean)。
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
看接下来的代码,这段代码主要用来判断它是不是BeanDefinitionRegistryPostProcessor,如果是,就调用postProcessBeanDefinitionRegistry方法(这个方法就是子接口BeanDefinitionRegistryPostProcessor实现的,并不是BeanFactory接口提供的),并把它放在registryProcessors列表中;如果不是,就把它放在regularPostProcessors列表中。遍历beanFactoryPostProcessors的列表,但是这里一般好像beanFactoryPostProcessors里都没东西,不用遍历。
那么Spring为什么要加这个逻辑呢?其实这是Spring作为一个框架留给我们的扩展点,我们可以手动往beanFactoryPostProcessors这个集合中添加一些BeanFactoryPostProcessor,让这些BeanFactoryPostProcessor在Spring内置的BeanFactoryPostProcessor执行之前就被执行。比如下面这段代码就会在Spring执行内置的BeanDefinitionRegistryPostProcessor之前先去执行我们自定义的BeanDefinitionRegistryPostProcessor的逻辑。
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
} else {
regularPostProcessors.add(postProcessor);
}
}
那么我们如何往这里添加BeanDefinitionRegistryPostProcessor,让它在这里就执行呢?我们可以使用如下的方式去手动添加。
//这里要使用AnnotationConfigApplicationContext去创建,不能使用ApplicationContext接口去创建
//因为addBeanFactoryPostProcessor方法是在AnnotationConfigApplicationContext中实现的
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(App.class); //手动注册
context.addBeanFactoryPostProcessor(new MyBeanDefinitionRegistryPostProcessor());
context.refresh();
这段代码是不是很熟悉?
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
this();
register(componentClasses);
refresh();
}
其实这就和我们传入一个componentClasses参数的方式很类似,我们只不过在refresh方法执行之前往容器中加入了我们自定义的BeanFactoryPostProcessor。
我们可以看到,我们自己加进去的PostProcessor在这里就已经能拿到了。这样,我们就成功添加了我们自己的PostProcessor,在Spring执行内置的PostProcessor之前,就会先执行我们自己先加进去的方式。
接下来是一个列表currentRegistryProcessors,这个列表中来存放当前正在执行的BeanDefinitionRegistryPostProcessor。
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
接着是这样一段代码,这段代码主要是拿到BeanDefinitionNames作为Key,再通过BeanDefinitionMap拿到BeanDefinition的Class是否实现了BeanDefinitionRegistryPostProcessor接口,如果实现了那么就将Key加入到postProcessorNames中,再根据BeanDefinitionName去BeanFactory中拿BeanDefinition,看它是否实现了PriorityOrdered接口。在invokeBeanDefinitionRegistryPostProcessors方法中则将这些PostProcessor进行实例化,调用getBean-doGetBean-createBean-doCreateBean一系列的方法去创建PostProcessor的Bean并进行执行。
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
//这里会执行Spring内置的PostProcessor--->
//ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry
//执行这里之后就会将我们自己实现的BeanRegistryPostProcessor扫描进来
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
//清除列表,避免重复执行
currentRegistryProcessors.clear();
需要注意的是使用如下的方式去拿到BeanFactory,由于构造方法中就执行了scan(basePackages)这个方法,将BeanDefinition已经加载到BeanDefinitionMap中。
ApplicationContext context = new AnnotationConfigApplicationContext("com.wanna.bean");
如果是使用的如下方式去拿到BeanFactory,则是在refresh方法的第二步执行的obtainFreshBeanFactory方法中将BeanDefinition加载到BeanFactory中的。
ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");
如果是使用的是如下方式去拿到BeanFactory,则是在 invokeBeanDefinitionRegistryPostProcessors这个方法中的postProcessor.postProcessBeanDefinitionRegistry(registry)这个步骤才将非Spring内置的BeanDefinition加载到BeanFactory中。使用这种方式在调用之前,BeanFactory中只有ConfigurationClassPostProcessor这一个BeanDefinition的Class是实现了PriorityOrdered接口的。在执行invokeBeanDefinitionRegistryPostProcessors时,调用的ConfigurationClassPostProcessor这个类的postProcessBeanDefinitionRegistry方法将用户自定义的BeanDefinition扫描进来。但是如果是使用另外的两种方式,这里调用之前就已经可以拿到我们自定义的BeanDefinitionRegistryPostProcessor的BeanDefinition了。
ApplicationContext context = new AnnotationConfigApplicationContext(App.class)
也就是到这里,无论哪种方式都已经将BeanDefinition加载到BeanFactory中,后面要用到只需要拿来进行创建Bean即可。
在invokeBeanDefinitionRegistryPostProcessors方法中还会将实现了PriorityOrdered接口的Bean给创建出来并执行postProcessBeanDefinitionRegistry。也就是如果我们自定义如下的BeanDefinitionRegistryPostProcessor,也会在这里执行postProcessBeanDefinitionRegistry方法,打印Wanna--postProcessBeanDefinitionRegistry这句话。
@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor, PriorityOrdered {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("Wanna-postProcessBeanFactory");
}
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
System.out.println("Wanna--postProcessBeanDefinitionRegistry");
}
@Override
public int getOrder() {
return 0;
}
}
接下来这段代码和上面的类似,只不过这里是调用的是实现了BeanDefinitionRegistryPostProcessor和Ordered接口的实现类(Bean)。在invokeBeanDefinitionRegistryPostProcessors方法中则将这些PostProcessor进行实例化,调用getBean-doGetBean-createBean-doCreateBean一系列的方法去创建PostProcessor的Bean并进行执行。
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, beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();
下面段代码也是很类似,调用的是实现了BeanDefinitionRegistryPostProcessor接口,但是没实现Ordered接口和PriorityOrdered接口的实现类(Bean)。在invokeBeanDefinitionRegistryPostProcessors方法中则将这些PostProcessor进行实例化,调用getBean-doGetBean-createBean-doCreateBean一系列的方法去创建PostProcessor的Bean并进行执行。
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, beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();
}
接着,下一段,这里第一个方法会调用BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法(需要说明的是,BeanDefinitionRegistryPostProcessor这个接口有两个方法,一个来自于BeanFactoryPostProcessor,另一个来自于BeanDefinitionRegistryPostProcessor自己实现的,上面调用的都只是postProcessBeanDefinitionRegistry方法,而这里调用的是postProcessBeanFactory方法),也就是Wanna-postProcessBeanFactory这句话会在第一个方法执行完之后打印,regularPostProcessors一般为null。在上面我们讲了会在执行Spring内置的BeanDefinitionRegistryPostProcessor之前可以执行我们自己使用API方式定义的BeanDefinitionRegistryPostProcessor。而这里调用的第二个方法其实就是保证我们使用API方式往容器中加入的普通BeanFactoryPostProcessor能够先执行,再执行其他的BeanFactory。
// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
下面一大段代码也是类似,只不过这里执行的是并没有实现BeanDefinitionRegistryPostProcessor,仅仅实现了普通BeanFactoryPostProcessor接口的实现类。也是依次执行实现了PriorityOrdered接口、Ordered接口、既没有实现PriorityOrdered又没有实现Ordered接口的实现类。利用BeanDefinition进行实例化,并调用postProcessBeanFactory方法。
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
// 2.将实现了PriorityOrdered、Ordered接口的BeanFactoryPostProcessor和剩下的分开并进行调用
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
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.
// 2.1将实现了PriorityOrdered接口的BeanFactoryPostProcessor进行排序并进行调用
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
// 2.2将实现了Ordered接口的BeanFactoryPostProcessor进行排序并调用
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// Finally, invoke all other BeanFactoryPostProcessors.
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
// 2.3调用既没有实现PriorityOrdered接口、也没有实现Ordered的BeanFactoryPostProcessor
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();