执行原理

31次阅读

共计 2653 个字符,预计需要花费 7 分钟才能阅读完成。

2.4 执行原理

​ 每个 Spring Boot 项目都有一个主程序启动类,在主程序启动类中有一个启动项目的 main() 方法,在该方法中通过执行 SpringApplication.run() 即可启动整个 Spring Boot 程序。

问题:那么 SpringApplication.run() 方法到底是如何做到启动 Spring Boot 项目的呢?

下面我们查看 run() 方法内部的源码,核心代码具体如下:

“`java

@SpringBootApplication

public class SpringbootDemoApplication {

public static void main(String[] args) {

SpringApplication.run(SpringbootDemoApplication.class, args);

}

}

“`

“`java

public static ConfigurableApplicationContext run(Class<?> primarySource,

String… args) {

return run(new Class[]{primarySource}, args);

}

public static ConfigurableApplicationContext run(Class<?>[] primarySources,

String[] args) {

return (new SpringApplication(primarySources)).run(args);

}

“`

​ 从上述源码可以看出,SpringApplication.run() 方法内部执行了两个操作,分别是 SpringApplication 实例的初始化创建和调用 run() 启动项目,这两个阶段的实现具体说明如下

**1.SpringApplication 实例的初始化创建 **

​ 查看 SpringApplication 实例对象初始化创建的源码信息,核心代码具体如下

“`java

public SpringApplication(ResourceLoader resourceLoader, Class… primarySources) {

this.sources = new LinkedHashSet();

this.bannerMode = Mode.CONSOLE;

this.logStartupInfo = true;

this.addCommandLineProperties = true;

this.addConversionService = true;

this.headless = true;

this.registerShutdownHook = true;

this.additionalProfiles = new HashSet();

this.isCustomEnvironment = false;

this.resourceLoader = resourceLoader;

Assert.notNull(primarySources, “PrimarySources must not be null”);

// 把项目启动类.class 设置为属性存储起来

this.primarySources = new LinkedHashSet(Arrays.asList(primarySources));

// 判断当前 webApplicationType 应用的类型

this.webApplicationType = WebApplicationType.deduceFromClasspath();

// 设置初始化器 (Initializer), 最后会调用这些初始化器

this.setInitializers(this.getSpringFactoriesInstances(

ApplicationContextInitializer.class));

// 设置监听器 (Listener)

this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));

// 用于推断并设置项目 main() 方法启动的主程序启动类

this.mainApplicationClass = this.deduceMainApplicationClass();

“`

从上述源码可以看出,SpringApplication 的初始化过程主要包括 4 部分,具体说明如下。

(1)this.webApplicationType = WebApplicationType.deduceFromClasspath()

用于判断当前 webApplicationType 应用的类型。deduceFromClasspath() 方法用于查看 Classpath 类路径下是否存在某个特征类,从而判断当前 webApplicationType 类型是 SERVLET 应用(Spring 5 之前的传统 MVC 应用)还是 REACTIVE 应用(Spring 5 开始出现的 WebFlux 交互式应用)

(2)this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class))

用于 SpringApplication 应用的初始化器设置。在初始化器设置过程中,会使用 Spring 类加载器 SpringFactoriesLoader 从 META-INF/spring.factories 类路径下的 META-INF 下的 spring.factores 文件中获取所有可用的应用初始化器类 ApplicationContextInitializer。

(3)this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class))

用于 SpringApplication 应用的监听器设置。监听器设置的过程与上一步初始化器设置的过程基本一样,也是使用 SpringFactoriesLoader 从 META-INF/spring.factories 类路径下的 META-INF 下的 spring.factores 文件中获取所有可用的监听器类 ApplicationListener。

(4)this.mainApplicationClass = this.deduceMainApplicationClass()

用于推断并设置项目 main() 方法启动的主程序启动类

正文完
 0