简介
调用bean工厂的后置处理器
解析
初始化三个集合
//第一步:首先调用BeanDefinitionRegistryPostProcessor的后置处理器
Set<String> processedBeans = new HashSet<>();
//保存BeanFactoryPostProcessor类型的后置
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
//保存BeanDefinitionRegistryPostProcessor类型的后置处理器
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
分别保存两种类型的后置处理器
第一个for循环
遍历外部传入的bean工厂后置处理器,当然这里为空,因为我们根本没传,只有是手动调用context.addBeanFactoryPostProcessor(xxx)才会有数据
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
//判断我们的后置处理器是不是BeanDefinitionRegistryPostProcessor
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
//进行强制转化
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
//调用他作为BeanDefinitionRegistryPostProcessor的处理器的后置方法
registryProcessor.postProcessBeanDefinitionRegistry(registry);
//添加到我们用于保存的BeanDefinitionRegistryPostProcessor的集合中
registryProcessors.add(registryProcessor);
}
else {//若没有实现BeanDefinitionRegistryPostProcessor 接口,那么他就是BeanFactoryPostProcessor
//把当前的后置处理器加入到regularPostProcessors中
regularPostProcessors.add(postProcessor);
}
}
获取beandefinitionRegistryPostProcessor
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
定义一个集合用户保存当前准备创建的BeanDefinitionRegistryPostProcessor
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
获取容器中BeanDefinitionRegistryPostProcessor的bean后置处理器名称,拿到的是internalConfigurationAnnotationProcessor
第二个for循环
for (String ppName : postProcessorNames) {
//判断是否实现了PriorityOrdered接口的
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
//显示的调用getBean()的方式获取出该对象然后加入到currentRegistryProcessors集合中去
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
//同时也加入到processedBeans集合中去
processedBeans.add(ppName);
}
}
循环刚刚拿到的bean后置处理器名称,判断是否实现了PriorityOrdered接口,然后将其添加到刚刚创建的缓存集合中,并且加入到processedBeans中
注意第5行,调用了getBean,将后置处理器实例化
对缓存集合cur中的元素进行排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
保存到registryProcessors中
registryProcessors.addAll(currentRegistryProcessors);
执行
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
执行缓存中的后置处理器,这里只有internalConfigurationAnnotationProcessor。
ConfigurationAnnotationProcessor
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
int registryId = System.identityHashCode(registry);
if (this.registriesPostProcessed.contains(registryId)) {
throw new IllegalStateException(
"postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
}
if (this.factoriesPostProcessed.contains(registryId)) {
throw new IllegalStateException(
"postProcessBeanFactory already called on this post-processor against " + registry);
}
this.registriesPostProcessed.add(registryId);
//真正的解析我们的bean定义
processConfigBeanDefinitions(registry);
}
调用postProcessBeanDefinitionRegistry方法,这里去调用真正解析processConfigBeanDefinitions,注意registry就是beanFactory
processConfigBeanDefinitions
进行配置类解析的方法,这里简要说明一下该类做了些什么事
- 首先是获取容器中所有的bean定义名称,然后进行遍历
- 通过bean定义名称获取bean定义对象,判断是否解析过。进行配置类检查是否标注@Configuration注解还是@bean注解
- 这里会解析出我们真正的配置类然后加入到配置类集合中
- 进行order排序, 然后调用parse进行解析配置类
- 解析完毕之后注册到容器中,并添加到已解析集合中
- 最后检查是否还有剩余没有解析的配置类,添加到候选集合中进行循环解析
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
//获取IOC 容器中目前所有bean定义的名称
String[] candidateNames = registry.getBeanDefinitionNames();
//循环我们的上一步获取的所有的bean定义信息
for (String beanName : candidateNames) {
//通过bean的名称来获取我们的bean定义对象
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
//判断是否有没有解析过
if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) ||
ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
if (logger.isDebugEnabled()) {
logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
}
}
//进行正在的解析判断是不是完全的配置类 还是一个非正式的配置类,將配置类添加集合中
else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
//满足添加 就加入到候选的配置类集合中
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}
// 若没有找到配置类 直接返回
if (configCandidates.isEmpty()) {
return;
}
//对我们的配置类进行Order排序
configCandidates.sort((bd1, bd2) -> {
int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
return Integer.compare(i1, i2);
});
// 创建我们通过@CompentScan导入进来的bean name的生成器
// 创建我们通过@Import导入进来的bean的名称
SingletonBeanRegistry sbr = null;
if (registry instanceof SingletonBeanRegistry) {
sbr = (SingletonBeanRegistry) registry;
if (!this.localBeanNameGeneratorSet) {
BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR);
if (generator != null) {
//设置@CompentScan导入进来的bean的名称生成器
this.componentScanBeanNameGenerator = generator;
//设置@Import导入进来的bean的名称生成器
this.importBeanNameGenerator = generator;
}
}
}
if (this.environment == null) {
this.environment = new StandardEnvironment();
}
//创建一个配置类解析器对象
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry);
//创建一个集合用于保存我们的配置类BeanDefinitionHolder集合默认长度是配置类集合的长度
Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
//创建一个集合用于保存我们的已经解析的配置类,长度默认为解析出来默认的配置类的集合长度
Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
//do while 会进行第一次解析
do {
//真正的解析我们的配置类
parser.parse(candidates);
parser.validate();
//解析出来的配置类
Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
configClasses.removeAll(alreadyParsed);
// Read the model and create bean definitions based on its content
if (this.reader == null) {
this.reader = new ConfigurationClassBeanDefinitionReader(
registry, this.sourceExtractor, this.resourceLoader, this.environment,
this.importBeanNameGenerator, parser.getImportRegistry());
}
//真正的把我们解析出来的配置类注册到容器中
this.reader.loadBeanDefinitions(configClasses);
//加入到已经解析的集合中
alreadyParsed.addAll(configClasses);
candidates.clear();
//判断我们ioc容器中的是不是>候选原始的bean定义的个数,原始的是6个后置处理器+配置类,候选的是原始的加上扫描出来的bean
if (registry.getBeanDefinitionCount() > candidateNames.length) {
//获取所有的bean定义
String[] newCandidateNames = registry.getBeanDefinitionNames();
//原始的老的候选的bean定义
Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
Set<String> alreadyParsedClasses = new HashSet<>();
//赋值已经解析的其他bean,不包含原始的bean
for (ConfigurationClass configurationClass : alreadyParsed) {
alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
}
for (String candidateName : newCandidateNames) {
//表示当前循环的还没有被解析过
if (!oldCandidateNames.contains(candidateName)) {
BeanDefinition bd = registry.getBeanDefinition(candidateName);
//判断有没有被解析过
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&
!alreadyParsedClasses.contains(bd.getBeanClassName())) {
candidates.add(new BeanDefinitionHolder(bd, candidateName));
}
}
}
candidateNames = newCandidateNames;
}
}
//存在没有解析过的 需要循环解析
while (!candidates.isEmpty());
// Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes
if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
}
if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
// Clear cache in externally provided MetadataReaderFactory; this is a no-op
// for a shared cache since it'll be cleared by the ApplicationContext.
((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
}}
这才调用完BeanDefinitionRegistryPostProcessors
现在回到invokeBeanFactoryPostProcessors中,invokeBeanDefinitionRegistryPostProcessors的逻辑才走完,现在再来看我们的beanDefinitionMap中
将cur缓存集合清空
再去容器中获取BeanDefinitionRegistryPostProcessors的bean处理器名称
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
还是只有ConfigurationAnnotationProcessor
遍历得到的bean处理器名称,获取没有处理过的处理器,并且实现了Order接口的
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class))
当然没有
还是 排序 – >保存集合 --> 执行方法 -->清空缓存 4连操作
进入一个while循环
再次去获取BeanDefinitionRegistryPostProcessors的bean处理器名称,还是只有那一个。再去4连操作一下。
退出循环
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
调用bean工厂后置处理器 区别 之前两次都是调用bean定义注册后置处理器
调用invokeBeanFactoryPostProcessors,这次是从已添加的集合中调用,不为空。注意这里是调用的bean工厂的后置处理器方法,不是bean定义注册的后置处理器方法
@Override
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)) {
// BeanDefinitionRegistryPostProcessor hook apparently not supported...
// Simply call processConfigurationClasses lazily at this point then.
processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
}
//使用cglib对配置类进行动态代理,因为@Bean方法到时候要进行Bean的实例化创建
enhanceConfigurationClasses(beanFactory);
beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
}
这里最后调用的add方法将beanFactory封装为一个ImportAwareBeanPostProcessor方法,作用是什么?
获取容器中所有的bean工厂后置处理器
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
创建集合
//保存BeanFactoryPostProcessor类型实现了priorityOrdered
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
//保存BeanFactoryPostProcessor类型实现了Ordered接口的
List<String> orderedPostProcessorNames = new ArrayList<>();
//保存BeanFactoryPostProcessor没有实现任何优先级接口的
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for循环
依次判断是否实现了PriorityOrdered接口和Ordered接口以及最后没有实现任何优先级的接口
分别加入到不同的集合中。
排序执行
先将实现了PriorityOrdered的进行排序然后执行
再是实现Ordered接口的进行排序执行
最后是没有实现任何接口的
到此结束
最后总结一下
整个过程无非就下面这几步
- 执行容器中的beanDefinitionRegisterPostProcessors
- 创建三个集合分别是保存已经执行过的bean定义注册后置处理器、保存bean定义注册的后置处理器和保存bean工厂后置处理器的集合
- for循环根据beanName从容器中获取后置处理器,然后遍历执行
- 第一次四连,执行postProcessBeanDefinitionRegistry。解析我们的配置类,实现priorityOrdered接口的
- 第二次去获取bean定义注册后置处理器,然后第二次四连,实现了ordered接口的
- 进入while循环,第三次去获取bean定义注册后置处理器
- 如果while循环并没有得到没有被处理过的处理器,那就跳出循环
- 调用保存bean定义注册后置处理器集合中的bean工厂后置处理器,执行这里会对配置类进行动态代理,并将beanfactory包装为一个ImportAwareBeanPostProcessor放入beanfactory的后置处理器中
- 调用保存bean工厂后置处理器集合中的bean工厂后置处理器
- 执行容器中的beanFactoryPostProcessors
- 获取容器中bean工厂后置处理器
- 创建三个集合,保存实现priorityOrdered接口的处理器、实现了Ordered接口的处理器和没有实现任何接口的处理器集合
- 遍历后置处理器,跳过已经执行过的。分别将不同接口的处理器加入对应集合中
- 按照priority、ordered和没有实现优先级接口的处理器顺序,依次调用执行
关于ConfigurationClassPostProcessor
这个类是内置的6个后置处理器之一,作用是在帮助解析配置类
在整个invokeBeanFactoryPostProcessors的执行过程中,该类有如下的调用
- 首先是在第一次获取后置处理器时,得到BeanDefinitionRegistryPostProcessor的实现类后置处理器,执行其postProcessBeanDefinitionRegistry方法。这里将所有的bean定义注册
- 然后在whilie循环结束之后,调用其postProcessBeanFactory方法创建配置类的动态代理