ConfigurationClassPostProcessor类,@Configuration注解的底层实现
概览
由前文可知,ConfigurationClassPostProcessor是作为Spring中的内置类被添加到容器中,
ConfigurationClassPostProcessor不仅实现了BeanFactoryPostProcessor(BFPP)并且实现了BeanDefinitionRegistryPostProcessor
,具有比一般BFPP更高的初始化优先级,在容器的启动过程中处理了@Configuration、@ComponentScan、@Import、@ImportResource注解,根据注解信息创建BeanDefinition。
主要流程
流程图
processConfigBeanDefinitions()
首先看processConfigBeanDefinitions方法,遍历了容器中的所有BD,并从中过滤出配置类
何为配置类?我们再接着看checkConfigurationClassCandidate
方法
配置类分为以下两种
- Full配置类,存在@Configuration,并且proxyBeanMethods不为false(为true或为null)时,就是Full配置类
- lite配置类:
- 存在@Configuration,并且proxyBeanMethods为false时,是lite配置类
- 不存在@Configuration,但是只要存在@Component、@ComponentScan、@Import、@ImportResource四个中的一个,就是lite配置类
- 不存在@Configurations,只要存在@Bean注解了的方法,就是lite配置类
parse()
找到所有配置类后,下一步是解析配置类,解析配置类的时候使用了do,while循环处理,这是因为每处理一个配置类,可能都会产生新的配置类,所以需要一直处理到不再有新的配置类产生。
- 处理内部类
如果类上有Component注解,判断内部类是否是配置类
- 处理@PropertySource
如果类上有类上有@PropertySource注解,处理引用的配置文件,解析到env
- 处理@ComponentScan
如果当前类是@ComponentScan,根据@ComponentScan注解属性创建一个Scanner,扫描路径下的Bean,注册为BD,如果BD是配置类,则立即解析配置类
- 处理Import
import引入的类默认为配置类,立即解析import的类
- 处理@Bean
找出类中所有@Bean的方法,此处没有直接处理,将方法记录到configClass中
postProcessBeanFactory()
此方法是接口BeanFactoryPostProcessor的实现,主要作用是为配置类生成代理对象,判断当前配置类是否是Full配置类,如果是Full配置类,使用cglib增强生成代理Bean