推断main方法的定义类,在运行前配置了哪些信息,调用run方法后一次进行了哪些操作
1. 创建SpringApplication
1.保存一些信息
2.判定当前应用的类型。ClassUtils工具类,(有Servlet和响应式编程)
查找加载环节:使用SpringFactoriesLoader去spring.factories
3.bootstrappers:初始启动引导器(List
4.ApplicationContextInitializer:应用上下文(环境)初始化,去spring.factories找
5.ApplicationListener:应用监听器,去spring.factories找
2.运行SpringApplication
1.StopWatch——统计代码计算时间,记录应用的启动时间
2.创建引导上下文(context环境) createBootstrapperContext()
获取到所有之前的bootstrappers挨个执行initialize(),完成对引导启动器上下文环境设置
3.让当前应用进入headless模式
4.获取所有RunListener(运行监听器),方便所有监听器进行事件感知
去spring.factories找SpringApplicationRunListener
5.遍历SpringApplicationRunListener,调用started()方法,告诉它们SpringBoot要开始工作了
6.保存命令行参数 ApplicationArguments
7.准备环境 prepareEnvironment()
返回或创建基础环境信息对象
配置环境信息对象
读取所有的配置源的配置属性值
绑定环境信息
监听器调用listener.environmentPrepared() 通知所有监听器当前环境准备完成
8.创建IOC容器 createApplicationContext()
根据项目类型创建容器
9.准备ApplicationContext IOC容器的基本信息 prepareContext()
保存环境信息
IOC容器的后置处理流程
应用初始化器 applyInitializers
遍历所有ApplicationContextInitializer,调用initialize() 对IOC容器进行初始化扩展功能
遍历listener调用contextPrepared EventPublishRunListener 通知所有监听器
10.刷新IOC容器 refreshContext
创建容器中的所有组件(Spring注解,最核心的一步:将之前通过@EnableAutoConfiguration获取的所有配置和其他形式的IOC容器配置加载到准备完毕的ApplicationContext中)
11.容器刷新完成后工作 afterRefresh
12.所有监听器调用listener.start(context) 开始监听
13.调用所有runners callRunners()
获取容器中的ApplicationRunner
获取容器中的CommandLineRunner
合并所有runner按照@Order排序
遍历runner 调用run方法
14.以上若有异常
调用Listener的failed
面试回答
springboot是通过main方法下的SpringApplication.run方法启动的
启动的时候他会调用refreshContext方法,先刷新容器
然后根据解析注解或者解析配置文件的形式注册bean
而它是通过启动类的@SpringBootApplication注解进行开始解析的
他会根据@EnableAutoConfiguration开启自动化配置
里面有个核心方法ImportSelect选择性的导入
根据loadFanctoryNames根据classpash路径以MATA-INF/spring.factorces下面以什么什么EnableAutoConfiguration开头的key去加载里面所有对应的自动化配置
// 引导——详细聊
他并不是把这一百二十多个自动化配置全部导入
在他每个自动化配置里面都有条件判断注解
1.先判断是否引入相互的jar包
2.再判断容器是否有bean
3.再进行注入到bean容器