面试的时候被人问springBoot的启动流程,鄙人直接回答不知道。于是面试完之后便就浅尝一下springBoot的启动流程,在此做个总结与回顾。
SringBoot的启动是通过下面这个代码触发的。
首先让我们看一下SpringApplication被实例化的时候经历过哪些事情。先读一下SpringApplication类的注释。说的内容大概如下:
SpringApplication用与main方法引导和启动Spring应用程序。默认情况下,将执行以下步骤来引导我们的应用程序。
-
创建一个恰当的 ApplicationContext 实例
-
注册CommandLinePropertySource(命令行属性源),将命令行参数公开为Spring属性
-
刷新应用程序上下文,加载所有单例Bean
-
触发全部的CommandLineRunner bean
实例化代码如下:
主要看四个方法
deduceWebApplicationType (推断web应用类型)
setInitializers (获取ApplicationContextInitializer工厂实例)
注:ApplicationContextInitializer:容器在初始化的时候应该做的一些事情
setListeners (获取ApplicationListener工厂实例)
注:ApplicationListener:当容器初始化完成之后的时候可以做的一些事情。例如一些数据的加载、初始化缓存、特定任务
deduceMainApplicationClass
注:从当前堆栈跟踪列表中获取main方法所在的类名
首先来看看deduceWebApplicationType方法
该方法的主要意思就是判断指定的类能不能进行加载,然后走相对应的判断逻辑,最终返回web的类型。
接着来看第二个方法(重点)
setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class))
SpringFactoriesLoader( spring工厂加载器 )
再来看看loadFactoryNames方法
主要做的事情就是:
- 查找类路径下全部的META-INF/spring.factories的URL
- 根据url加载全部的spring.factories中的属性
- 将加载完成之后的结果存入到静态map中方便下次使用。
- 再通过loadSpringFactories(classLoader).getOrDefault(factoryClassName, Collections.emptyList())方法,从中获取指定工厂类型的工厂名称列表。
再回到
当loadFactoryNames方法执行完毕之后就调用createSpringFactoriesInstances方法,创建指定类型的工厂实例。
最后我们再来看一下createSpringFactoriesInstances方法
SpringApplication实例化总结:
- 构造自身需要的属性
- 判断web应用的类型,并赋值到webApplicationType属性中
- 设置List< ApplicationContextInitializer > List<ApplicationListener>属性
- 判断主类,并赋值到mainApplicationClass