整体流程
1.SpringApplication 静态调用run 方法,从静态run 方法中new 一个自己的实例,并调用实例的run方法。
2.构造方法中会初始化容器一些属性,主要是初始化两个数据集合:
a.配置文件中以ApplicationContextInitializer为 key 的初始化器的实例集合。
b.配置文件中以ApplicationListener为key 的程序启动监听器的实例集合。
以及推断出类的WebApplicationType(REACTIVE\SERVLET\NONE)
和启动类mainApplicationClass。
3.run方法启动流程:
主要有6步:
a.获取并启动监听的listeners
b.初始化应用环境
c.初始化应用上下文
d.刷新应用上下文前的准备工作
e.刷新应用上下文
f.刷新应用上下文之后的扩展功能
4.ApplicationContextInitializer 与监听器的读取
a.调用SpringApplication#getSpringFactoriesInstances,传入需要预先加载的初始化器的类型
b.因为是第一次加载,缓存中没有从配置文件中读取所有的数据。因此根据classloader读取所有模块META-INF/spring.factories中的配置数据,以map<String,List<String>>形式存储在缓存中。
c.读取b路径下的配置数据详情
可以看到,ApplicationContextInitializer对应的初始化器有7个
初始化器的详情
d.初始化器实例初始化
e.应用的监听listeners,加载方式同上述的初始化器的加载流程,
5.run启动流程
1.读取SpringApplicationRunListener ,依旧是读取的从配置文件中的数据,同上方加载流程相同。
2.初始化应用环境
a.创建应用环境
b.配置环境属性
c.通知环境数据加载完成
3.创建应用上下文
根据应用类型,读取对应的类的全路径名称,并初始化
4.应用上下文刷新前的准备工作
加载启动类流程
5.刷新应用上下文
进入spring容器得的refresh 方法,主要观察invokeBeanFactoryPostProcessors 实现
进入方法后,其实是调用了代理类的invokeBeanFactoryPostProcessors
继续进入后,读取beanFactoryProcessors,两个初始化器和一个listener 的processor
经过寻找,得到类型为BeanDefinitionRegistryPostProcessor 的容器name ,在根据name从容器中获取实例集合,本次只有一个--org.springframework.context.annotation.internalConfigurationAnnotationProcessor
继续向下,进入invokeBeanDefinitionRegistryPostProcessors,触发ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry
调用自身的processConfigBeanDefinitions,里面会初始化ConfigurationClassParser
进入parse方法
一直深入到doProcessConfigurationClass中,该方法会被递归调用,里面会扫描Component注解的类,并将需要import的配置类也收集到一起
解析配置后,获取解析结果,可以看到系统的配置类与自定义得controller 都解析到了
之后就是执行spring容器流程了
fancoder:Spring 源码浅析
@SpringBootApplication注解
集合注解,集合了三个注解:
@SpringBootConfiguration主要是封装了@Configuration
@EnableAutoConfiguration集成了两个注解
@AutoConfigurationPackage,封装了@Import,导入了AutoConfigurationPackages.Registrar,自动封装包
根据注解元信息,获取包名,注册到容器
将启动类所在的包名作为跟路径存到容器
@Import 导入AutoConfigurationImportSelector
主要负责将spring.facotries中的配置自动配置类EnableAutoConfiguration对应的配置类加载到容器