浏览Spring源码书籍或者看视频时,都先入为主的讲解xml解析到spring容器启动。但是这年头早就开始用springboot集成各种组件并启动spring容器了,那么问题来了:到底spring是在哪里开始解析项目中的各个注解的呢?
解析过程(给出大概步骤)
spring中注解配置类的解析源码流程:
- springApplication.run
- 在环境配置完成后会调用createApplicationContext()创建上下文。
- 根据推断如果是SERVLET,则创建AnnotationConfigServletWebServerApplicationContext
- AnnotationConfigServletWebServerApplicationContext构造中会创建两个变量
public AnnotationConfigServletWebServerApplicationContext() {
//1.创建注解beanDefinition解析器
this.reader = new AnnotatedBeanDefinitionReader(this);
//2.项目目录扫描器
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
- 创建reader时,会调用AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
- 这里会创建6个BeanDefinition到bean容器中:
ConfigurationClassPostProcessor//配置类解析器
AutowiredAnnotationBeanPostProcessor//autowired解析器
RequiredAnnotationBeanPostProcessor//required解析器
CommonAnnotationBeanPostProcessor//@Resource解析器
EventListenerMethodProcessor//事件监听
DefaultEventListenerFactory//默认事件监听器工厂 - 调用spring的refresh核心方法中的invokeBeanFactoryPostProcessors方法
- 会调用ConfigurationClassPostProcessor的后置处理器方法
- processConfigBeanDefinitions(registry);
- 遍历所有beandefinition,调用ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)。
- 这个方法根据beandefinition类型,如果是注解类型就通过AnnotatedBeanDefinition.getMetadata更新元信息。然后通过元信息判断是哪种类型:
Configuration注解的是full类型
Component、ComponentScan、Import、ImportResource注解的或者存在方法被@Bean注解的是lite类型。
然后判断被Order注解标注的给beanDefinition赋值。 - 创建解析类ConfigurationClassParser的对象
- 对配置类,对于springboot来说就是入口类进行解析。
- 容器中是否存在importRegistry实例,不存在则创建。
- 清除缓存
对于想了解细节的提供一个大概的思路。
ConfigurationClassUtils核心解析流程.png
网友评论