Spring Boot 是一个用于构建独立的、生产级别的 Spring 应用程序的框架。它简化了基于 Spring 的应用开发,通过提供默认配置和自动配置功能,使得开发者能够更快速地启动和运行应用程序。
Spring Boot 启动流程
1、 启动入口
Spring Boot 应用的启动通常从一个包含 main() 方法的主类开始。这个主类会使用 @SpringBootApplication 注解,它实际上是一个组合注解,包括了 @SpringBootConfiguration、@EnableAutoConfiguration 和 @ComponentScan 三个注解。
java
@SpringBootApplication
public class MySpringBootApplication {
public static void main(String[] args) {
SpringApplication.run(MySpringBootApplication.class, args);
}
}
2、创建 SpringApplication 对象
当调用 SpringApplication.run() 方法时,Spring Boot 会首先创建一个 SpringApplication 对象。这个对象负责管理 Spring 应用的启动和初始化过程。
java
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
this.resourceLoader = resourceLoader;
Assert.notNull(primarySources, "PrimarySources must not be null");
this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
this.webApplicationType = WebApplicationType.deduceFromClasspath();
// 设置默认的banner模式
setBannerMode(Banner.Mode.CONSOLE);
this.listeners = new CopyOnWriteArrayList<>();
this.mainApplicationClass = deduceMainApplicationClass();
}
在 SpringApplication 对象创建后,会进行一系列初始化工作,包括:
- 推断应用类型:判断应用是 Web 应用还是非 Web 应用。
- 加载初始化器:从 META-INF/spring.factories 文件中加载 ApplicationContextInitializer 实现类。
- 加载监听器:从 META-INF/spring.factories 文件中加载 ApplicationListener 实现类。
- 推断主配置类:通过反射找到包含 main() 方法的主类。
3、运行 SpringApplication
SpringApplication 对象调用其 run() 方法,该方法是启动流程的核心。
java
public ConfigurableApplicationContext run(String... args) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
FailureAnalyzers analyzers = null;
configureHeadlessProperty();
SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting();
try {
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
Banner printedBanner = printBanner(environment);
context = createApplicationContext();
analyzers = new FailureAnalyzers(context);
prepareContext(context, environment, listeners, applicationArguments, printedBanner);
refreshContext(context);
listeners.started();
callRunners(context, applicationArguments);
} catch (Throwable ex) {
handleRunFailure(context, ex, analyzers);
throw new IllegalStateException(ex);
}
stopWatch.stop();
listeners.finished(stopWatch);
return context;
}
run() 方法执行了以下关键步骤:
3.1 准备环境
在应用上下文准备前,Spring Boot 会先准备环境(Environment),这包括:在启动过程中,Spring Boot 会准备应用环境(Environment),这包括:
- 读取配置文件:加载 application.properties 或 application.yml 等配置文件。
- 解析命令行参数:将命令行参数解析为环境属性。
- 收集系统环境变量:将系统环境变量添加到环境属性中。
java
ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
3.2 初始化应用上下文
根据你选择的 web 环境类型(如 Servlet 或 Reactive),Spring Boot 会设置合适的应用上下文(ApplicationContext)。对于 Web 应用,通常会创建 AnnotationConfigServletWebServerApplicationContext;对于非 Web 应用,则会创建 AnnotationConfigApplicationContext。
java
ConfigurableApplicationContext createApplicationContext() {
return new SpringApplication().createApplicationContext();
}
3.3 加载 Bean 定义
Spring Boot 会通过扫描类路径中的组件和配置类(由 @ComponentScan 和 @Configuration 等注解指定)来加载 Bean 定义。
Spring Boot 使用组件扫描机制来自动发现并注册应用程序中的 @Component、@Service、@Repository 和 @Controller 等注解标注的 Bean。此外,Spring Boot 还支持通过 @Configuration 类定义的 Bean。
4、自动配置
@EnableAutoConfiguration 注解激活了自动配置功能。Spring Boot 会根据项目中添加的 jar 依赖,尝试猜测并配置你可能需要的 Bean。自动配置类会在应用上下文中被条件化地执行。
5、刷新应用上下文ApplicationContext
完成所有配置后,Spring Boot 会刷新应用上下文。此时,所有的 Bean 都已注册完毕,且已准备就绪。这个过程包括:
- 实例化 Bean:根据 Bean 定义创建 Bean 实例。
- 初始化 Bean:调用 Bean 的初始化方法。
- 注册 Bean:将 Bean 注册到应用上下文中,使其可供应用使用。
java
refreshContext(context);
6、应用就绪
最后,Spring Boot 会发布一个 ApplicationReadyEvent,表明应用已完全启动并准备好接收请求。
Spring Boot 启动原理
Spring Boot 的启动原理主要基于以下几个核心特性:
1、自动配置
Spring Boot 通过查看 classpath 和已定义的 beans 来决定配置类的自动应用。这是通过 @EnableAutoConfiguration 注解实现的。Spring Boot 会根据项目中包含的依赖项自动配置应用程序的各种组件。
2、起步依赖(Starter)
Spring Boot 提供了一组起步依赖,每个起步依赖都旨在简化构建配置,提供所需的依赖。这使得开发者能够快速开始一个功能完备的开发环境,而无需担心版本冲突。
3、外部化配置
Spring Boot 允许通过外部配置(如 properties 文件、YAML 文件、环境变量和命令行参数)来管理应用程序的配置。这使得应用能够在不同环境中使用相同的代码,而无需重新构建。
4、内嵌服务器
Spring Boot 内置了常见的服务器(如 Tomcat、Jetty 或 Undertow),使得开发者无需复杂的服务器配置即可快速启动和运行应用程序。
总结
Spring Boot 通过其简洁的启动流程和强大的自动配置功能,极大地简化了基于 Spring 的应用开发。开发者只需关注业务逻辑和所需的依赖库,即可快速构建出可运行的应用程序。通过深入了解 Spring Boot 的启动流程和原理,开发者可以更好地利用这一框架,提高开发效率和质量。