上一篇我们将
AnnotationConfigApplicationContext构造函数的整体流程梳理一遍,今天我们来详细聊聊Spring是如何扫描得到所有需要被管理的Bean信息的,这里用一个专业名词来表示Bean信息叫BeanDefinition,后面我们都简称BD,我们后面会有专门章节来说明BD的类继承关系。
上一篇我们讲到
invokeBeanFactoryPostProcessors是完成扫描的核心方法,那么我们进入该方法来看看:
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
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()));
}
}
关键代码就是
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()),在进一入invokeBeanFactoryPostProcessors方法:
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
Set<String> processedBeans = new HashSet<>();
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
// 关键点一、这个beanFactoryPostProcessors集合一般情况下都是空的,除非我们手动调用容器的addBeanFactoryPostProcessor方法
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}else {
regularPostProcessors.add(postProcessor);
}
}
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
//关键点二、执行BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法
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);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
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();
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();
}
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}else {
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
//关键点三
String[] postProcessorNames =beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
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);
}
}
//关键点四、执行BeanFactoryPostProcessor的postProcessBeanFactory方法
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
beanFactory.clearMetadataCache();
}
代码有点多,但是归纳起来就做了两件事:第一执行
BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法,也就是对BeanDefinition进行处理;第二执行BeanFactoryPostProcessor的postProcessBeanFactory方法,执行BeanFactory的后置处理器逻辑。下面我们就来详细说说。
- 关键点一
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}else {
regularPostProcessors.add(postProcessor);
}
}
beanFactoryPostProcessors一般情况下都是空的,除非我们手动调用容器的
addBeanFactoryPostProcessor方法,这里Spring提供了一个扩展点,一般情况下不会使用。
- 关键点二
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
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);
}
}
首先:
看currentRegistryProcessors这个对象,他的主要作用就是记录当前将要执行的
BeanDefinitionRegistryPostProcessor实例,首先获取到所有的BeanDefinitionRegistryPostProcessor,然后将PriorityOrdered类型的BeanDefinitionRegistryPostProcessor对象添加到currentRegistryProcessors集合中。注意这里获取到的BeanDefinitionRegistryPostProcessor类型对象只有一个ConfigurationClassPostProcessor,那这个类是什么时候添加到BeanFactory里面去的呢?咱们还记得上一篇构造函数里面创建了一个reader对象吗?代码如下:
this.reader = new AnnotatedBeanDefinitionReader(this);
AnnotatedBeanDefinitionReader的构造函数中调用了如下代码:
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
这段代码中创建了五个类型的对象,并将这五个类型对象添加到了BeanFactory中:
1.ConfigurationClassPostProcessor
2.AutowiredAnnotationBeanPostProcessor
3.CommonAnnotationBeanPostProcessor
4.EventListenerMethodProcessor
5.DefaultEventListenerFactory
而
ConfigurationClassPostProcessor又实现了BeanDefinitionRegistryPostProcessor和PriorityOrdered:
public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor,
PriorityOrdered, ResourceLoaderAware, BeanClassLoaderAware, EnvironmentAware {...}
然后执行如下代码:
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
这里开始执行上述的
ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry方法,这个方法就是扫描得到所有的BeanDefinition,由于这里比较复杂,后续我们专门文章来分析,这里先跳过,大家只要知道它的作用即可。
其次:
依次类推,将执行Ordered.class类型的
BeanDefinitionRegistryPostProcessor实例对象。
最后
需要执行普通的
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();
}
但是很奇怪,这里为啥要加个while循环?Spring有病吧?当然没病,人家Spring考虑的周全。这里表示执行上面没有执行的
BeanDefinitionRegistryPostProcessor,而且你在执行过程中,可能会产生新的BeanDefinitionRegistryPostProcessor对象,所以才用个while循环,直到执行完所有的BeanDefinitionRegistryPostProcessor才结束;
执行完后,再执行
BeanDefinitionRegistryPostProcessor实现类的postProcessBeanFactory方法(因为BeanDefinitionRegistryPostProcessor也是BeanFactoryPostProcessor的实现),这里就会执行ConfigurationClassPostProcessor的postProcessBeanFactory方法:
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
ConfigurationClassPostProcessor的postProcessBeanFactory方法有点特别:
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
int factoryId = System.identityHashCode(beanFactory);
if (this.factoriesPostProcessed.contains(factoryId)) {
throw new IllegalStateException(
"postProcessBeanFactory already called on this post-processor against " + beanFactory);
}
this.factoriesPostProcessed.add(factoryId);
if (!this.registriesPostProcessed.contains(factoryId)) {
processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
}
enhanceConfigurationClasses(beanFactory);
beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
}
enhanceConfigurationClasses这个方法用于判断是否需要对配置类生成代理对象?什么是配置类?增加了@Configuration注解的类是配置了,它有什么特点呢?凡是在配置类中被@Bean声明的对象都需要代理,所以这里需要对@Configuration类型的对象进行特殊处理;
然后添加
ImportAwareBeanPostProcessor后置处理器,这个是对@import注解进行处理的Bean的后置处理器,后续我们再讲。
- 关键点三
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);
}
}
这里看代码很简单,就是把所有的BeanFactoryPostProcessor对象分别放到三个集合里面去,然后按优先级先后执行
priorityOrderedPostProcessors、orderedPostProcessorNames、nonOrderedPostProcessorNames中的BeanFactoryPostProcessor对象,但是为什么不像上面的BeanDefinitionRegistryPostProcessor一样处理,而是直接分到三个集合里面呢?这个也很简单,因为执行BeanFactoryPostProcessor方法不会产生新的BeanFactoryPostProcessor对象,所以为了提升效率,直接分组到不同的集合即可。
- 关键点四
这里就开始执行BeanFactoryPostProcessor的postProcessBeanFactory方法了,先执行
priorityOrderedPostProcessors集合中的,其次执行orderedPostProcessorNames集合中的,最后执行nonOrderedPostProcessorNames集合中的。