调用时间点
Springboot应用启动过程中,会进行beanDefinitions注册,其调用时间点如下:
可以看出在PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors函数进行BeanDefinitions的注册。
流程详解
BeanDefinitions注册
在PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors中第一次调用invokeBeanDefinitionRegistryPostProcessors根据注解进行BeanDefinitons的注册。在此函数中会迭代入参postProcessors,调用postProcessor#postProcessBeanDefinitionRegistry,此时的入参为:
由于postProcessors长度为1,实际就是调用ConfigurationClassPostProcessor#postProcessBean DefinitionRegistry,根据注解进行BeanDefinitions的注册。
ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry函数又调用processConfigBeanDefinition函数,也即:
ConfigurationClassPostProcessor#processConfigBeanDefinitions函数,会过滤候选配置类,根据配置类来注册BeanDefinitions,其流程图如下:
迭代配置候选列表注册BeanDefinitions,此时会在迭代中调用ConfigurationClassPraser#parse方法进行具体的注册,该函数的入参为上面流程图过滤出来的配置候选列表,该函数的处理流程图如下:
最终调用ConfigurationClassParser#processConfigurationClass函数来进行BeanDefinitions的注册,在第一次调用时,该函数的入参为:
processConfigurationClass的处理逻辑为,如果配置类有父类,会继续递归调用,根据父类中的注解进行BeanDefinitions的注册:
从上图可以看到,工作都是在ConfigurationClassParser#doProcessConfigurationClass中做的,此函数的处理流程图如下:
如上三个流程图的流程,其实都是“子流程A”的迭代配置候选表的一部分,其代码为:
至此,第一次调用PostProcessorRegistrationDelegate#invokeBeanDefinitionRegistryPostProc essors结束。
接着,再次在beanFactory中查找类型为BeanDefinitionRegistryPostProcessor.class且有@Order注解且在第一次调用中未处理过的(即在第一次中新增的),第二次调用PostProcessorRegistrationDelegate# invokeBeanDefinitionRegistryPostProcessors:
第二次调用后,循环检查上次执行PostProcessorRegistrationDelegate# invokeBeanDefinitionRegistryPostProcessors是否有新添加的类型BeanDefinitionRegistryPostProcessor,如果有,则继续调用PostProcessorRegistrationDelegate# invokeBeanDefinitionRegistryPostProcessors:
至此所有BeanDefinitions扫描结束。
最后,调用BeanFactoryPostProcessor,调用的优先级是@PriorityOrdered>@Ordered>无前述两个注解的。
至此,BeanDefinitions注册流程结束。