Spring 5.x 源码之旅九invokeBeanFactoryPostProcessors二
ConfigurationClassParser加载bean定义还有一点尾巴
循环解析加载bean定义
上一篇讲了是一次解析加载bean
定义的过程,其实外面是个循环,因为你加载了bean
定义后,可能会有新的配置类的bean
定义,所以也要进行解析和加载bean
,因此是一个循环。我省略了部分代码,把主要的循环流程和判断留下来了。其实就是循环处理新加载进来的配置类的bean
定义,直到没有为止。
do {//开始解析configCandidates元素
parser.parse(candidates);//解析配置类集合
parser.validate();//验证如果要CGLIB代理的话,条件是否满足,比如类不能final,bean注解
this.reader.loadBeanDefinitions(configClasses);//加载bean定义
...
if (registry.getBeanDefinitionCount() > candidateNames.length) {//如果有加载到新的bean定义,再继续加载
...
for (String candidateName : newCandidateNames) {
if (!oldCandidateNames.contains(candidateName)) {//处理新的
BeanDefinition bd = registry.getBeanDefinition(candidateName);
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&
!alreadyParsedClasses.contains(bd.getBeanClassName())) {//符合配置类要求就添加到candidates
candidates.add(new BeanDefinitionHolder(bd, candidateName));
}
}
}
candidateNames = newCandidateNames;//更新候选名字
}
}
while (!candidates.isEmpty());
注册单例importStack
把importStack
注册为单例,为了支持ImportAware
接口扩展,说明已经处理Import
注解过了。
if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
}
清除字节码元数据缓存
有些bean
定义的元数据是通过URL
加载字节码文件解析来的,为了避免每次都去IO
操作,会有元数据的缓存,现在处理完了就要把缓存清除了。
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();
}
BeanDefinitionRegistryPostProcessor后置处理器处理流程
处理一般排序的BeanDefinitionRegistryPostProcessor后置处理器
至此ConfigurationClassPostProcessor
的处理完成了,也就是有优先级PriorityOrdered
的后置处理器处理好了,现在要处理一般顺序Ordered
的处理器了,这段代码跟前面的一样,只是这次是取一般顺序的处理器,执行的是一样的流程,这里还是再次获取BeanDefinitionRegistryPostProcessor
类型的,会把所有的都获取出来,当然包括处理过的,不过没关系,处理过的处理器会放入processedBeans
中,不会再次处理的:
//再次获取没处理过的BeanDefinitionRegistryPostProcessors且实现Ordered接口的来处理,因为可能前面处理后产生新的bean定义
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
//没处理过的,而且是Ordered类型的
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);
其实这里也可能是PriorityOrdered类型的,是通过前面解析出来的。比如我们来看这个扩展点。
扩展点实战一
比如创建了一个TestBeanDefinitionRegistryPostProcessorPriorityOrdered
实现了BeanDefinitionRegistryPostProcessor
和Ordered
。
public class TestBeanDefinitionRegistryPostProcessorPriorityOrdered implements BeanDefinitionRegistryPostProcessor, PriorityOrdered {
public TestBeanDefinitionRegistryPostProcessorPriorityOrdered(){
System.out.println("TestBeanDefinitionRegistryPostProcessorPriorityOrdered被创建了");
}
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
System.out.println("MyBeanDefinitionRegistryPostProcessorPriorityOrdered postProcessBeanDefinitionRegistry");
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("MyBeanDefinitionRegistryPostProcessorPriorityOrdered postProcessBeanFactory");
}
//排序的值,越小越前面
@Override
public int getOrder() {
return 1;
}
}
然后配置类里面用bean
注解方法,直接返回这个实例类型,我这里为了方便,其实应该返回接口类型,另外写一个接口类型比较好的。
@Configuration
public class MyConfig {
@Bean
public TestBeanDefinitionRegistryPostProcessorPriorityOrdered myRegistrar(){
return new TestBeanDefinitionRegistryPostProcessorPriorityOrdered();
}
}
执行的结果就是会被创建出来,然后执行postProcessBeanDefinitionRegistry
方法:
注意
这里要注意,这个时候因为要创建TestBeanDefinitionRegistryPostProcessorPriorityOrdered
处理器,所以MyConfig
也会被创建出来,作为单例。
循环处理最后剩下的BeanDefinitionRegistryPostProcessor后置处理器
最后就处理剩下的那些后置处理器,比如我在前面的扩展点再注册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);
currentRegistryProcessors.clear();
}
扩展点实战二
还是刚才的TestBeanDefinitionRegistryPostProcessorPriorityOrdered
,我在postProcessBeanDefinitionRegistry里自定义注册了一个bean
定义TestBeanDefinitionRegistryPostProcessor
。
他就会在最后被getBeanNamesForType
找到执行。
public class TestBeanDefinitionRegistryPostProcessorPriorityOrdered implements BeanDefinitionRegistryPostProcessor, PriorityOrdered {
public TestBeanDefinitionRegistryPostProcessorPriorityOrdered() {
System.out.println("TestBeanDefinitionRegistryPostProcessorPriorityOrdered被创建了");
}
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
System.out.println("MyBeanDefinitionRegistryPostProcessorPriorityOrdered postProcessBeanDefinitionRegistry");
AnnotatedBeanDefinition genericBeanDefinition=new AnnotatedGenericBeanDefinition(TestBeanDefinitionRegistryPostProcessor.class);
registry.registerBeanDefinition("TestBeanDefinitionRegistryPostProcessor",genericBeanDefinition);
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("MyBeanDefinitionRegistryPostProcessorPriorityOrdered postProcessBeanFactory");
}
//排序的值,越小越前面
@Override
public int getOrder() {
return 1;
}
}
TestBeanDefinitionRegistryPostProcessor
也是BeanDefinitionRegistryPostProcessor
类型的,扩展方法里又注册了一个UserDaoImple
。
public class TestBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
System.out.println("MyBeanDefinitionRegistryPostProcessor postProcessBeanDefinitionRegistry");
registry.registerBeanDefinition("UserDaoImple",new AnnotatedGenericBeanDefinition(UserDaoImple.class));
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("MyBeanDefinitionRegistryPostProcessor postProcessBeanFactory");
}
}
结果:
而且在里面又注册了一个UserDaoImple
:
至此,所有实现的BeanDefinitionRegistryPostProcessor
接口的处理器都处理完成了。
我们的自定义扩展顺序可以看这里:
扩展点顺序
ConfigurationClassPostProcessor
处理MyConfig
,MyConfig
定义了TestBeanDefinitionRegistryPostProcessorPriorityOrdered
的bean
注解方法,可以被加载进bean
定义。
TestBeanDefinitionRegistryPostProcessorPriorityOrdered
的postProcessBeanDefinitionRegistry
方法中注册了TestBeanDefinitionRegistryPostProcessor
的bean
定义。
TestBeanDefinitionRegistryPostProcessor
中的postProcessBeanDefinitionRegistry
又注册了UserDaoImple
的bean
定义。
注意
这个时候你会发现创建处理器的同时把配置类也创建了。
至此BeanDefinitionRegistryPostProcessor
的处理器全部处理完成,包括自定义的。后面就要处理BeanFactoryPostProcessor
的处理器啦,这个后面讲。
好了,今天就到这里了,希望对学习理解有帮助,大神看见勿喷,仅为自己的学习理解,能力有限,请多包涵。