#spring boot 启动
大概流程:
- 启动
- 实例 SpringApplication
a. 获取继承ApplicationContextInitializer接口的类名集合->实例化
b. 获取继承ApplicationListener接口的类名集合->实例化 c. 确认是否是web环境,获取启动时的main执行类,set souces -> 一般是启动时的类.class,如果是命令行启动我猜测是new Object[0] - 执行 run()
a. 启动时间观察器 StopWatch 实例化,并启动
b. 获取继承SpringApplicationRunListener接口的类名并实例化listeners
(A new will be created for each run,基本上上面的Initializer,Listener 都是通过这个实例执行的)
c. listeners.starting() -> 通知 2.b 所有listener.onApplicationEvent(event);能start的开始启动
d. 开始加载配置信息-> args 执行main方法或命令行似的参数封装
e. 打印banner -> 控制台输出springboot 和版本号
f. 终于开始实例化 AnnotationConfigEmbeddedWebApplicationContext(web环境下实例化的使这个,其他环境不是这个),实例化或通过3.b 步骤的SpringApplicationRunListener 通知各个listener动起来,例如ConfigFileApplicationListener
开始寻找并加载application.properties
以及当前环境(开发,生产,测试等)
g. ApplicationContext.refresh().这个是主菜,上下文环境什么的都加载好了,这个方法一运行,就可以看见熟悉的日志开始滚动,至此基本上springboot启动的差不多了 h. 通知各个listener refresh() 完成,停止启动时间观察,输出结果.......完
以上所说的获取继承**接口,在springboot中是扫描jar中
META-INF/spring.factories
对应的配置,例如:
# Application Context Initializers
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer,\
org.springframework.boot.context.ContextIdApplicationContextInitializer,\
org.springframework.boot.context.config.DelegatingApplicationContextInitializer,\
org.springframework.boot.context.embedded.ServerPortInfoApplicationContextInitializer
通过键值队的方式获取接口对应的类.