我们知道spring在启动的过程中,会调用refresh()方法,而refresh()方法会调用invokeBeanFactoryPostProcessors(beanFactory);通过方法名称可以知道其实就是执行BeanFactoryPostProcessor,它在spring中是一个BeanFactory的后置处理器,作用是对BeanFactory进行加工。但是spring启动到这里,beanFactory中只有一个BeanFactoryPostProcessor,就是ConfigurationClassPostProcessor,而解析配置类的过程就是调用这个类的postProcessBeanDefinitionRegistry()方法实现的。
解析配置类流程
1、书写以下配置类代码,启动spring;首先从beanFactory中拿到所有的BeanDefinition,判断是否存在配置类,不存在直接返回,存在就添加到一个集合中。
@ComponentScan("com.xxx")
public class AppConfig {
}
什么是配置类?
(1)存在@Configuration(full配置类)
(2)不存在@Configuration,但是存在@Component、@ComponentScan、@Import、@ImportResource四个中的一个就是配置类(lite配置类)
(3)不存在@Configuration,只要类中存在@Bean注解了的方法(就是lite配置类)
(4)存在@Configuration,但是其属性proxyBeanMethods=false,是lite配置类
2、对配置类集合进行排序。通过@Orderd排序,数值越小在前面
3、创建ConfigurationClassParser对象,用来解析ConfigurationClass(配置类对象)
4、把类的元信息和beanName封装成ConfigurationClass;判断是否有@Conditional注解(这里不清楚)
5、判断配置类上是否存在@Component注解,存在就去找内部类是否也是配置类,并解析
6、如果配置类中存在@PropertySources注解,这个注解可以导入一个文件,并将文件中内容解析到容器中environment中
7、如果存在@ComponentScans,或者@ComponentScan注解,则进行扫描,扫描到符合条件的类会被解析为BeanDefinition,并注册到spring容器中去。这里判断扫描出来的是不是配置类,如果是,则进行递归。
8、如果配置类上存在@Import注解,
(1)如果导入的是普通的类,直接把它当成配置类来解析,也就是解析成BeanDefinition
(2)如果导入的是普通ImportSelector,则调用其接口方法selectImports(),并将返回结果spring数组解析为BeanDefinition,注册到spring容器中去
(3)如果导入的是DeferredImportSelector,那么会延迟执行接口方法。最后会在所有配置类解析完成之后执行接口方法selectImports()
(4)如果导入的是ImportBeanDefinitionRegistrar类,则加载这个类并生成一个实例对象,添加到ConfigurationClass的属性importBeanDefinitionRegistrars集合中。其中集成mybatis就是他的功能。
9、处理@ImportResource,拿到导入的资源路径和BeanDefinition读取器,添加到ConfigurationClass的属性importedResources集合中
10、解析@Bean,解析配置类中所有的@Bean注解的方法,封装为BeanMethod对象,添加配置类中beanMethods属性中
11、解析配置类中实现的接口中的@Bean方法,并没有真正处理,只是找出来,也是添加配置类中beanMethods属性中
12、解析配置类中的父类,添加到knownSuperclasses属性中。
13、处理@Import所导入的类,@Bean,@ImportResource,实现ImportBeanDefinitionRegistrar(8,9,10,11)中解析出来的类并解析为BeanDefinition并注册到spring容器中去
14、如果发现BeanDefinition增加了,则有可能增加了配置类,继续解析配置类
BeanFactoryPostProcessor的执行顺序
1. 执行手动添加的BeanDefinitionRegistryPostProcessor 的postProcessBeanDefinitionRegistry()方法
2. 执行扫描出来的BeanDefinitionRegistryPostProcessor(实现了PriorityOrdered)的postProcessBeanDefinitionRegistry()方法--------解析配置类
3. 执行扫描出来的BeanDefinitionRegistryPostProcessor(实现了Ordered) 的postProcessBeanDefinitionRegistry()方法
4. 执行扫描出来的BeanDefinitionRegistryPostProcessor(普通) 的postProcessBeanDefinitionRegistry()方法
5. 执行扫描出来的BeanDefinitionRegistryPostProcessor(所有) 的postProcessBeanFactory()方法
6. 执行手动添加的BeanFactoryPostProcessor 的postProcessBeanFactory()方法
7. 执行扫描出来的BeanFactoryPostProcessor(实现了PriorityOrdered) 的postProcessBeanFactory()方法
8. 执行扫描出来的BeanFactoryPostProcessor(实现了Ordered) 的postProcessBeanFactory()方法
9. 执行扫描出来的BeanFactoryPostProcessor(普通) 的postProcessBeanFactory()方法 *