深入解析Spring Boot启动原理:从零开始掌握
深入解析Spring Boot启动原理:从零开始掌握
大家好,今天我们来聊聊Spring Boot的启动原理。Spring Boot作为一个简化Spring应用开发的框架,已经成为Java开发者的首选工具之一。它的启动过程看似简单,但背后却有很多值得我们深入探讨的机制。本文将带你一步步揭开Spring Boot启动的神秘面纱。
1. Spring Boot启动流程概述
Spring Boot的启动过程主要包括以下几个步骤:
- 启动类的执行:通常是一个包含
@SpringBootApplication
注解的主类。 - SpringApplication的初始化:Spring Boot通过
SpringApplication
类来启动和管理Spring应用。 - 准备环境:包括读取配置文件、设置系统属性等。
- 创建并刷新应用上下文:加载所有的Bean定义并初始化应用上下文。
- 完成启动:执行所有的
CommandLineRunner
和ApplicationRunner
。
下面我们将逐步深入每一个步骤。
2. 启动类的执行
首先,我们来看一个最简单的Spring Boot应用启动类:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MySpringBootApplication {
public static void main(String[] args) {
SpringApplication.run(MySpringBootApplication.class, args);
}
}
这个类包含了一个main
方法,调用了SpringApplication.run
方法来启动应用。
3. SpringApplication的初始化
SpringApplication.run
方法实际上是一个静态方法,它会创建一个SpringApplication
实例并调用其run
方法。我们来看一下SpringApplication
的构造函数:
public SpringApplication(Class<?>... primarySources) {
this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
this.webApplicationType = WebApplicationType.deduceFromClasspath();
setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
this.mainApplicationClass = deduceMainApplicationClass();
}
在这个构造函数中,Spring Boot做了几件重要的事情:
- 确定应用类型:根据类路径中的依赖来判断是普通的Spring应用还是Web应用。
- 设置初始化器:从
spring.factories
文件中加载所有的ApplicationContextInitializer
。 - 设置监听器:从
spring.factories
文件中加载所有的ApplicationListener
。 - 推断主类:找到包含
main
方法的主类。
4. 准备环境
接下来,SpringApplication.run
方法会调用prepareEnvironment
方法来准备环境:
private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments) {
// Create and configure the environment
ConfigurableEnvironment environment = getOrCreateEnvironment();
configureEnvironment(environment, applicationArguments.getSourceArgs());
listeners.environmentPrepared(environment);
bindToSpringApplication(environment);
if (!this.isCustomEnvironment) {
environment = new EnvironmentConverter(getClassLoader()).convertEnvironmentIfNecessary(environment, deduceEnvironmentClass());
}
ConfigurationPropertySources.attach(environment);
return environment;
}
在这个方法中,Spring Boot会创建并配置ConfigurableEnvironment
,读取配置文件,设置系统属性等。
5. 创建并刷新应用上下文
环境准备好之后,Spring Boot会创建应用上下文并加载所有的Bean定义:
private void refreshContext(ConfigurableApplicationContext context) {
refresh(context);
if (this.registerShutdownHook) {
try {
context.registerShutdownHook();
} catch (AccessControlException ex) {
// Not allowed in some environments.
}
}
}
refresh
方法会触发一系列的事件,包括Bean的创建和初始化。
6. 完成启动
最后,Spring Boot会执行所有的CommandLineRunner
和ApplicationRunner
,完成启动过程:
private void callRunners(ApplicationContext context, ApplicationArguments args) {
List<Object> runners = new ArrayList<>();
runners.addAll(context.getBeansOfType(CommandLineRunner.class).values());
runners.addAll(context.getBeansOfType(ApplicationRunner.class).values());
AnnotationAwareOrderComparator.sort(runners);
for (Object runner : new LinkedHashSet<>(runners)) {
if (runner instanceof CommandLineRunner) {
callRunner((CommandLineRunner) runner, args);
}
if (runner instanceof ApplicationRunner) {
callRunner((ApplicationRunner) runner, args);
}
}
}
结语
通过以上步骤,我们详细解析了Spring Boot的启动过程。希望这篇文章能帮助你更好地理解Spring Boot的内部机制。如果你有任何问题或建议,欢迎在评论区留言。感谢阅读!
下次我们将深入探讨Spring Boot的自动配置原理,敬请期待!
百万大学生都在用的AI写论文工具,篇篇无重复👉: AI写论文