SpringApplication
这个类应该算是 Spring Boot 框架 本身的“创新”产物了,因为原始的Spring框架中并没有这个类,SpringApplication
里面封装了一套Spring应用的启动流程,然而这对用户完全透明,因此我们上手 Spring Boot 时感觉简洁且轻量。
一般来说默认的 SpringApplication
执行流程已经可以满足大部分需求,但是 若用户想干预这个过程,则可以通过 SpringApplication
在流程某些地方开启的 扩展点 来完成对流程的扩展,典型的扩展方案那就是使用 set
方法。
我们来举一个栗子,把我们天天司空见惯的 Spring Boot 应用的启动类来拆解一下写出来:
@SpringBootApplication
public 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实例的初始化
还是先对照代码来看:
图片四个关键的步骤已标注在图中,分别解释如下:
① 推断应用的类型:创建的是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 应用上下文准备完毕后,执行一些额外操作。从而完成最终的程序的启动。 -
由
SpringApplicationRunListener
来发出running
消息,告知程序已运行起来了
网友评论