

· 正 · 文 · 来 · 啦 ·
上一篇文章我们讲到了SpringBoot借助@SpringBootConfiguration
@EnableAutoConfiguration @ComponentScan三个注解实现了自动化的配置,从而省去了开发人员编写繁杂的XML文件的问题。
今天我们继续来聊一下SpringBoot的启动问题,我们知道只需执行以下代码就能使一个SpringBoot项目启动起来,那么SpringApplication.run()到底有什么魔力呢?今天我们就来探究一下吧。
public static void main(String[] args) {
SpringApplication.run(SpringbootDemoApplication.class, args);
}
我们直接来看看源码。
public static void main(String[] args) {
SpringApplication.run(SpringbootDemoApplication.class, args);
}
我们看到是SpringApplication类的一个静态方法run(),我们继续跟踪进去。
public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {
return run(new Class<?>[] { primarySource }, args);
}
又转进了另一个run()方法我们继续跟踪。
public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
return new SpringApplication(primarySources).run(args);
}
在这一步,它实例化了一个SpringApplication对象,并调用了它的run()方法。
我么一步一步来,就先来看一下SpringApplication的实例化。
SpringApplication的实例化源码如下:

从这段代码中我们看到SpringApplication的实例化主要有四个步骤,已在上图标注。
(1) 推断应用的类型:创建的是 REACTIVE应用、SERVLET应用、NONE 三种中的某一种。

(2)使用SpringFactoriesLoader查找并加载 classpath下 META-INF/spring.factories文件中所有可用的ApplicationContextInitializer。

(3)使用SpringFactoriesLoader查找并加载 classpath下 META-INF/spring.factories文件中的所有可用的 ApplicationListener。

(4)对 main方法的定义类进行推断

到此SpringApplication对象的实例化我们就完成了,那么SpringApplication对象实例化之后就要调用它的run()方法了,这个run()方法内部又是如何呢?
先来看一下run()方法的源码。

如上图所示,run()方法主要有10个关键点组成。我们来逐一看一下各个步骤。
①通过 SpringFactoriesLoader 加载META-INF/spring.factories 文件,获取并创建SpringApplicationRunListener 对象

②由 SpringApplicationRunListener 来发出 starting 消息

③、创建参数,并配置当前 SpringBoot 应用将要使用的 Environment
④完成之后,依然由 SpringApplicationRunListener 来发出environmentPrepared 消息

⑤、创建 ApplicationContext
⑥、初始化 ApplicationContext,并设置 Environment,加载相关配置等。
由 SpringApplicationRunListener 来发出 contextPrepared 消息,告知 SpringBoot 应用使用的 ApplicationContext 已准备OK。
将各种 beans 装载入ApplicationContext,继续由 SpringApplicationRunListener 来发出 contextLoaded 消息,告知 SpringBoot 应用使用的 ApplicationContext 已装填OK

⑦、refresh ApplicationContext,完成IoC容器可用的最后一步

⑧、由 SpringApplicationRunListener 来发出 started 消息
⑨、如果没有报错的话,就以完成程序的启动
⑩、由 SpringApplicationRunListener 来发出 running 消息,告知程序已运行起来了
看了整个流程头是不是有些晕,我们来看个示意图梳理一下。

这就是SpringBoot的启动流程,是不是很清晰了!
通过今天的文章,相信大家对SpringBoot的启动原理有了更深入的理解,更多关于SpringBoot的原理知识我们下次再聊。







