springboot版本,1.4.3.RELEASE
流水账,纯记录。
TL;DR.
- 创建并初始化SpringBoot实例
- 判断是否是web应用 : 通过是否存在Web应用相关的类来判断,
javax.servlet.Servletorg.springframework.web.context.ConfigurableWebApplicationContext - 从
META-INF/spring.factories中加载ApplicationContextInitializer的实现类,为之创建实例,并按照注解Order来排序存储,getSpringFactoriesInstances - 从
META-INF/spring.factories中加载ApplicationListener的实现类,为之创建实例,并按照注解Order来排序存储,getSpringFactoriesInstances - 判断应用程序主类 : 分析当前调用栈,找到含有
main方法的类。不过这里只检查了方法名,若是还有其他名为main的方法,容易出现错误。
- 判断是否是web应用 : 通过是否存在Web应用相关的类来判断,
- 调用
SpringApplication#run(String... args)启动应用程序 :- 从
META-INF/spring.factories中加载SpringApplicationRunListener的实现类,为之创建实例,并按照注解Order来排序存储,然后在启动加载的实例SpringApplicationRunListeners#started
- 从
- 处理命令行参数,
DefaultApplicationArguments- 按照是否带有前缀
--来区分是否是参数选项,分别存储到CommandLineArgs的optionArgs和nonOptionArgs中,参见SimpleCommandLineArgsParser#parse
- 按照是否带有前缀
- 准备应用程序的执行环境,
prepareEnvironment- 创建
Environment实例,若是Web应用程序,则使用StandardServletEnvironment实例,否则使用StandardEnvironment实例。在实例化Environment时,会获取到系统变量和环境变量,放置到属性列表中。 - 配置创建好的
Environment实例,将命令行参数中的配置项加入到属性列表中,配置profile信息,找出处理active状态的profile - 调用注册的
SpringApplicationRunListeners,处理environmentPrepared事件 - 若创建的
Environment实例是ConfigurableWebEnvironment,但前面通过deduceWebEnvironment方法判断的不是Web应用,则会将ConfigurableWebEnvironment实例转换为普通Environment实例。
- 创建
- 在控制台打印banner文字
- 创建
ApplicationContext容器,对于Web应用程序,容器实例是AnnotationConfigEmbeddedWebApplicationContext。容器有两个属性,AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner,分别用来根据注解和类路径来加载Bean。注意,这时候还没有加载Bean。 - 准备容器
ApplicationContext- 将
ApplicationContext与Environment相关联:context.setEnvironment(environment); - 处理
ApplicationContext实例,注册BeanBeanNameGenerator和ResourceLoader - 应用初始化器
ApplicationContextInitializer,对ApplicationContext实例,初始化器是在初始化SpringBoot实例时加载的 - 调用注册的
SpringApplicationRunListeners,处理contextPrepared事件 - 向容器
ApplicationContext中注册BeanApplicationArguments和Banner - 加载应用程
- 调用注册的
SpringApplicationRunListeners,处理contextLoaded事件
- 将
- 刷新容器
ApplicationContext- 准备刷新
- 清空容器属性
ClassPathBeanDefinitionScanner的缓存 - 调用父类,执行基础准备工作
- 重置容器启动时间,将关闭状态置为
false,将活动状态置为true - 初始化属性源,若当前是Web应用,则使用
GenericWebApplicationContext来初始化属性源,GenericWebApplicationContext#initPropertySources - 校验必要属性是否设置
- 重置容器启动时间,将关闭状态置为
- 清空容器属性
- 刷新
BeanFactory,这里其实啥也没做 - 准备
BeanFactory,做各项基础配置 BeanFactory后续处理,这里除了做常规的后续处理之外,还会使用实例ClassPathBeanDefinitionScanner和AnnotatedBeanDefinitionReader来加载应用程序的Bean- 调用
BeanFactoryPostProcessor - 注册
BeanPostProcessor - 初始化
MessageSource - 初始化事件广播器
ApplicationEventMulticaster - 初始化特殊Bean
- 注册
ApplicationListener,如果有早期事件的话,就会广播出去 - 实例化单例Bean
- 广播相关事件
- 准备刷新
- 刷新容器后的后续处理,这里主要是调用
ApplicationRunner和CommandLineRunner完成各自的任务 - 调用注册的
SpringApplicationRunListeners,处理finished事件