- 主类加载。一般为ApplicationLoader,具体名称,因人而异,也不重要。
- 加载SpringApplication类,并实例化SpringApplication。在实例化过程中,有以下关键步骤
- 确定当前程序的WebApplicationType。(SERVLET、REACTIVE、NONE)。【这里确定类型的代码平时在编程过程中可以使用】
- 加载类路径中的所有(任何一个jar包中出现的配置,一般来说,是各种starter中配置)的META-INF/spring.factories文件信息并解析为map。后续称之为spring工厂配置。
- 根据步骤2中已解析出来的spring工厂配置信息,设置SpringApplication类的initializers(List<ApplicationContextInitializer<?>)及listeners(List<ApplicationListener<?>)。
- 解析主类的类信息并赋值。【此处使用构建运行时异常及main函数匹配的trick方式,获取主类类名,日常编程过程中可以借鉴】
- 调用SpringApplication类的run方法。
- 从spring工厂配置信息中获取SpringApplicationRunListener类型的配置信息,并以此初始化SpringApplicationRunListeners类,用于springboot启动事件分发。
- 分发springboot启动事件,允许监听者实例运行启动回调。
- 包装main函数入参数为ApplicationArguments,用于后续向环境中注入以及向springContext中注册相应的bean实例。
- 构建环境信息封装类实例。
- 读取环境信息
- 分发springboot环境初始化结束事件,允许监听者进行应用程序环境信息的定制化操作。
- 将环境变量中配置的spring.main.*数据配置到SpringApplication类中。【此处使用Binder,后续可以研究一下】
- 根据应用程序的WebApplicationType,生成相应的ApplicationContext对象。
- 默认初始化AnnotationConfigServletWebServerApplicationContext对象。
- 初始化AnnotationBeanDefinitionReader实例
- 初始化一个ConditionEvalEvaluator实例。
- 向BeanFactory注册注解配置处理器实例。这里对理解注解类配置解析非常重要。【此处内容后续需要再细细看下】
- 注册ConfigurationClassPostProcessor类的beanDefinition信息。该类是一个BeanFactoryPostProcessor接口实现,具体调用时间参考applicationContext.refresh中的周期。
- 注册AutowiredAnnotationBeanPostProcessor类的beanDefinition信息。该类是一个BeanProcessor接口实现,主要在bean生成之后被调用。
- RequiredAnnotationBeanPostPorcessor类信息注册。
- CommonAnnotationBeanPostProcessor类信息注册。
- 等等。
- 初始化ClasspathBeanDefinitionReader实例。
- 初始化AnnotationBeanDefinitionReader实例
- 默认初始化AnnotationConfigServletWebServerApplicationContext对象。
- 设置applicationContext对象的环境封装实例。
- 使用spring工厂配置中的initializers对applicationContext进行定制化操作
- 分发context准备完毕信息。允许监听者对applicationContext进行定制化操作
- 注册springApplicationArguments单例,springBoot单例。
- 加载应用程序中的beanDefinition信息。这里主要是使用AnnotationBeanDefinitionReader实例,读取注解类型的配置信息,加载相应的beanDefinition信息。至此,基本上的配置信息均已加载完毕。
- 分发context加载完毕信息。允许监听者对applicationContext进行定制化操作。
- 调用refresh方法。这块大家都知道。
- 分发启动完成事件。
- 分别获取AppicationRunner类型bean及CommandLineRunner类型的bean,排序后依次调用