springboot自学(6)springboot核心原理
Springboot启动流程
- 初始化各种属性,加载成对象
读取环境属性(Environment)
系统配置(spring.factories)
参数(Arguments、application.properties)
- 创建Spring容器对象ApplicationContext,加载各种配置
- 在容器创建前,通过监听器机制,应对不同阶段加载数据、更新数据的要求
- 容器初始化过程中追加各种功能,例如统计时间、输出日志等
第一步启动来,run方法
进入run方法
primarySource属性指的就是启动类Springboot30StartupApplication,接下来再进入run方法
这是new了一个对象,加载各种配置信息,初始化各种配置对象,然后调用了run这个方法初始化容器,接下来进入SpringApplication这个方法
这个方法里调用了自己的构造方法,传了一个resourceLoader(资源加载器),点击this进入构造方法
第一行是把传进来的resourceLoader初始化成了成员变量(资源加载器),方便后续本方法和其他的方法使用;
第二行断言,判断一下primarySource是不是null;
第三行是把可变参数primarySource去重转换成了集合类型的对象保存到成员变量中
第四行的方法进去看看
这个方法是判断并返回web应用的容器类型
第五行的方法是从SpringFactories的配置中获得springboot系统引导注册初始化的信息,
进入方法
第1行先创建了一个BootstrapRegistryInitializer的集合;
第2行通过getSpringFactoriesInstances的方法针对Bootstrapper.class获得了SpringFactoriesInstances的信息,里面进行了一系列的设定然后放入集合
第3行又通过getSpringFactoriesInstances的方法针对BootstrapRegistryInitializer.class获得的信息也加入了集合,进入这个方法
还有有一个方法,再进入
第1行拿到类加载器
第2行,初始化了一个集合,把要加载的所有东西提取出来,得到要加载所有东西的名称
第3行,根据这个名称,创建对应的实例,得到了所有的实例对象
第4行,对实例对象进行了排序
第5行,返回实例
第六行 设置初始化信息,又使用到了getSpringFactoriesInstances方法,这回加载的是ApplicationContextInitializer.class的信息
这只是这个spring.factories里的,其他的文件里也可能有
第七行 设置监听器,还是调用了getSpringFactoriesInstances方法,这回加载的是ApplicationListener.class的信息(自定义的监听器可以做很多的事情)
别忘了在spring.factories里配置上
第八行 初始化了引导类的类名信息(备用的)
接下来看run方法,初始化容器,得到一个ApplicationContext对象
第一行创建秒表(StopWatch),是的,就是一个计时器
第二行启动了计时器开始计时了,后面在第十八行停止的
这个就是计时器的反馈时间,看代码可知,springboot没有把之前读取文件的时间算在内。
第三行创建的是系统引导信息对应的上下文对象
第四行声明了一个对象
第五行进入这个方法
这个方法里系统级的设置了一个属性,模拟输入输出信号,避免出现因缺少外设导致的信号传输失败,进而引发错误(模拟显示器,键盘,鼠标...)
第1行是设置"java.awt.headless"这个值
第2行是设置方法里面的参数,前面的是取了"java.awt.headless"这个值,后面是如果没取到就用this.headless的值,如果去取到了,就用取到的值
其实就是配置了java.awt.headless = true
第六行获取当前注册的所有监听器
第七行监听器执行了对应的操作步骤
第九行拿参数
第十行将前期读取的数据加载成了一个环境对象,用来描述信息
第十一行做了一个配置,备用
第十二行初始化启动图标
第十三行创建容器对象,根据前期配置的容器类型进行判定并创建
第十四行设置应用启动的启动模式
第十五行对容器进行设置,参数来源于前期的设定
第十六行刷新容器环境
第十七行刷新完毕后做的后处理
第十八行计时器关闭
第十九行是判断这个logStartupInfo是否为true(默认是true)
第二十行是通过判断以后,创建一个启动信息的日志对象,记录了mainApplicationClass的启动信息
第二十一行监听器执行了对应的操作步骤
第二十二行调用了运行器
第三十行监听器执行了对应的操作步骤
整个方法所有的核心就是context = this.createApplicationContext();前面是创建容器前的各项参数准备工作,后面是把准备好的参数放到容器里