SpringBoot 有两个关键元素:
@SpringBootApplication SpringApplication 以及 run() 方法
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 ); SpringApplication app = new SpringApplication( CodeSheepApplication.class ); app.setXXX( ... ); // 这里有用户自定的扩展 !!!! app.run( args ); } }
拆卸后,我们发现我们也需要先结构 SpringApplication 类对象,然后调用对象 run() 方法。然后我们来谈谈。 SpringApplication 的构造过程 以及其 run() 方法的过程,搞清楚了这一点,也就搞清楚了SpringBoot应用程序是如何运行的!
SpringApplication 实例的初始化 我们比较代码:
图中标注了四个关键步骤,分别说明如下:
① 推断应用类型:创建的是 REACTIVE应用,SERVLET应用,NONE 三种中的一种
② 使用 搜索SpringFactoriesloder claspath下的classpath META-INF/spring.factories文件中所有可用的 ApplicationContextInitializer
③ 使用 搜索SpringFactoriesloder claspath下的classpath META-INF/spring.factories文件中所有可用的 ApplicationListener
④ 推断并设置 main方法的定义类别
SpringApplication 探索run()方法 先看看代码是什么样子的:
我已经在上图中标注了所有的主要步骤。此外,我还根据自己的理解绘制了一个流程图,如下所示。您可以根据数字标记进行比较:
我们将每一步总结如下:
1、通过 SpringFactoriesLoader 加载 META-INF/spring.factories 获取和创建文件 SpringApplicationRunListener 对象
2、然后由 SpringApplicationRunListener 来发出 starting 消息
3、创建参数并配置当前参数 SpringBoot 将要使用的应用程序 Environment
4、完成后,还是由 SpringApplicationRunListener 来发出 environmentPrepared 消息
5、创建 ApplicationContext
6、初始化 ApplicationContext,并设置 Environment,加载相关配置等
7、由 SpringApplicationRunListener 来发出 contextPrepared 通知SpringBoot通知新闻 应用使用的 ApplicationContext 已准备OK
8、将各种 beans 装载入 ApplicationContext,继续由 SpringApplicationRunListener 来发出 contextLoaded 消息,告知 SpringBoot 应用使用的 ApplicationContext 已装填OK
9、refresh ApplicationContext,完成IOC容器可用性的最后一步
10、由 SpringApplicationRunListener 来发出 started 消息
11、完成最终程序的启动
12、由 SpringApplicationRunListener 来发出 running 消息,通知程序已经运行
到目前为止,整个过程都结束了!