搞笑,用了3年的SpringBoot框架,却不知是怎么启动的
文章插图
概 述在Java后端开发领域 , 大名鼎鼎的Spring Boot框架想必大家都用过 。
用过Spring Boot的应该都知道 , 在项目启动入口的主类main()方法里 , 一句简简单单的
SpringApplication.run( ... );
便开启了项目的启动运行之路 。
文章插图
那么本文我们就来看看这个 SpringApplication 以及 run() 方法 到底是个什么鬼 , 它背后又隐藏了哪些奥秘呢?
SpringApplication一瞥SpringApplication 这个类应该算是 Spring Boot 框架 本身的“创新”产物了 , 因为原始的Spring框架中并没有这个类 , SpringApplication 里面封装了一套Spring应用的启动流程 , 然而这对用户完全透明 , 因此我们上手 Spring Boot 时感觉简洁且轻量 。
一般来说默认的 SpringApplication 执行流程已经可以满足大部分需求 , 但是 若用户想干预这个过程 , 则可以通过 SpringApplication 在流程某些地方开启的 扩展点 来完成对流程的扩展 , 典型的扩展方案那就是使用 set 方法 。
我们来举一个例子 , 把我们天天司空见惯的 Spring Boot 应用的启动类来拆解一下写出来:
@SpringBootApplicationpublic class CodeSheepApplication { public static void main( String[] args ) {// SpringApplication.run( CodeSheepApplication.class args ); // 这是传统Spring Boot应用的启动 , 一行代码搞定 , 内部默认做了很多事SpringApplication app = new SpringApplication( CodeSheepApplication.class );app.setXXX( ... ); // 用户自定的扩展在此 !!!app.run( args ); }}
这样一拆解后我们发现 , 我们也需要先构造 SpringApplication 类对象 , 然后调用该对象的 run() 方法 。
那么接下来就聊聊 SpringApplication 的构造过程 以及其 run()方法的流程 , 搞清楚了这个 , 那么也就搞清楚了Spring Boot应用是如何运行起来的了 。
SpringApplication实例的初始化【搞笑,用了3年的SpringBoot框架,却不知是怎么启动的】还是先对照代码来看:
文章插图
四个关键的步骤已标注在图中 , 分别解释如下:
- ① 推断应用的类型:创建的是REACTIVE应用、SERVLET应用、NONE 三种中的某一种
文章插图
- ② 使用SpringFactoriesLoader查找并加载classpath下META-INF/spring.factories文件中所有可用的 ApplicationContextInitializer
文章插图
- ③ 使用SpringFactoriesLoader查找并加载classpath下META-INF/spring.factories文件中的所有可用的 ApplicationListener
文章插图
- ④ 推断并设置main方法的定义类
文章插图
SpringApplication的run()方法探秘先看看代码长啥样子:
文章插图
关键步骤都已经用数字标注在上图之中了 , 除此之外 , 这里也画了一个流程图对照理解:
文章插图
我们将各步骤总结精炼如下:
- 通过 SpringFactoriesLoader 加载 META-INF/spring.factories 文件 , 获取并创建 SpringApplicationRunListener 对象
- 然后由 SpringApplicationRunListener 来发出 starting 消息
- 创建参数 , 并配置当前 SpringBoot 应用将要使用的 Environment
- 完成之后 , 依然由 SpringApplicationRunListener 来发出 environmentPrepared 消息
- 创建 ApplicationContext
- 初始化 ApplicationContext , 并设置 Environment , 加载相关配置等
- 由 SpringApplicationRunListener 来发出 contextPrepared 消息 , 告知Spring Boot 应用使用的 ApplicationContext 已准备OK
- 将各种 beans 装载入 ApplicationContext , 继续由 SpringApplicationRunListener 来发出 contextLoaded 消息 , 告知 Spring Boot 应用使用的 ApplicationContext 已装填OK
- refresh ApplicationContext , 完成IoC容器可用的最后一步
- 由 SpringApplicationRunListener 来发出 started 消息
- 调用callRunners(...)方法 , 让实现了ApplicationRunner和CommandLineRunner接口类的run 方法得以执行 , 用于在 Spring 应用上下文准备完毕后 , 执行一些额外操作 。 从而完成最终的程序的启动 。
- 车企|华为不造车!但任正非加了一个有效期,3年
- 先别|用了周冬雨的照片,我会成为下一个被告?自媒体创作者先别自乱阵脚
- 巨头|“社区薇娅”都不够用了 一线互联网巨头全员下场卖菜
- 手机|iPhone12 Pro居然比mini还好卖?网友:24期免息起作用了!
- 谁给了|3年价格翻5倍,快“用不起”的共享充电宝,谁给了它涨价的底气
- 好评|1933年的一份“快递”,1949年才送到,虽相隔16年,却得国人好评
- 提问|比特币创近3年新高,再迎终极提问:比特币是钱吗?
- R2|「集微拆评」坚果R2评测:旗舰配置加独有功能,手机更好用了
- 激光雷达的强大,iPhone只用了个皮毛
- 微软启用新方式优化Win10:更好用了