type
status
date
slug
summary
tags
category
icon
password
Spring Boot 是一个简化了基于 Spring 框架的应用程序开发的框架。它提供了许多开箱即用的特性,能够快速构建独立的、生产级别的 Spring 应用程序,而无需繁琐的配置。要理解 Spring Boot 的启动机制,首先需要了解它是如何启动的,以及背后所涉及的一些关键组件和流程。
一、Spring Boot 启动概述
Spring Boot 应用程序通常以一个独立的 JAR 包形式运行,通过内嵌的 Web 服务器(如 Tomcat、Jetty 等)来处理 HTTP 请求。启动一个 Spring Boot 应用程序,只需要运行
main
方法即可,而不需要像传统的 Spring 应用程序那样进行复杂的 XML 配置。这种简洁的启动方式背后隐藏了许多自动配置和初始化的过程。二、Spring Boot 启动流程详解
1. SpringApplication 类
Spring Boot 的启动从
SpringApplication.run()
方法开始。这个方法是整个应用程序启动的入口,主要完成以下几个步骤:- 创建 SpringApplication 实例:
SpringApplication.run()
方法会首先创建一个SpringApplication
对象,这个对象是 Spring Boot 应用启动过程中的核心类。它负责引导应用程序的启动流程,初始化环境,加载应用上下文等。
- 判断应用类型:
SpringApplication
会根据类路径中的内容来判断当前应用是一个 Web 应用还是一个非 Web 应用。如果存在spring-web
相关的依赖,它会识别为 Web 应用,并相应地创建AnnotationConfigServletWebServerApplicationContext
,否则创建AnnotationConfigApplicationContext
。
- 设置启动器和初始器:Spring Boot 支持通过
ApplicationContextInitializer
和ApplicationListener
在应用启动过程中进行扩展。SpringApplication
会扫描和设置这些启动器和初始器,以便在不同的生命周期阶段进行回调。
- 启动引导监听器:在应用启动的早期阶段,
SpringApplication
会启动一些ApplicationListener
,这些监听器能够监听应用程序的生命周期事件并作出响应。
- 准备环境:
SpringApplication
会创建并配置应用的环境(Environment
)。环境包括系统环境变量、配置文件中的属性等。这些配置会决定应用在启动时的行为。
- 创建 ApplicationContext:根据应用类型,
SpringApplication
会创建对应的ApplicationContext
,这是 Spring 的核心容器,负责管理应用中的所有 Bean。
- 刷新 ApplicationContext:
SpringApplication
完成所有配置后,调用refresh()
方法刷新ApplicationContext
,这一步会触发 Bean 的初始化、注入和加载。
- 启动嵌入式 Web 服务器:如果是 Web 应用,
SpringApplication
会启动内嵌的 Web 服务器,并将ApplicationContext
中的 Web 组件绑定到服务器上。
- 执行运行时回调:
SpringApplication
最后会调用所有实现了CommandLineRunner
或ApplicationRunner
接口的 Bean,允许开发者在应用完全启动后执行特定的逻辑。
- 管理退出代码:当应用程序结束时,
SpringApplication
会根据应用的退出状态码进行处理,并最终退出 JVM。
2. Spring Boot 自动配置机制
Spring Boot 的核心之一就是其自动配置(Auto Configuration)能力,这使得开发者无需手动配置大量的 Bean 和组件。自动配置主要通过注解
@EnableAutoConfiguration
实现。@EnableAutoConfiguration
注解:这个注解告诉 Spring Boot 根据类路径中的依赖自动配置 Bean。Spring Boot 会扫描META-INF/spring.factories
文件中定义的EnableAutoConfiguration
条目,并加载相应的配置类。
- 条件配置:自动配置类通常会配合条件注解(如
@ConditionalOnClass
,@ConditionalOnMissingBean
)使用。Spring Boot 只会在特定条件满足时才会应用自动配置。例如,只有在类路径中存在某个类时,Spring Boot 才会自动配置相关的 Bean。
- 优先级和排除:开发者可以通过配置
spring.autoconfigure.exclude
属性来排除特定的自动配置类,或者通过@AutoConfigureBefore
和@AutoConfigureAfter
注解来调整自动配置的顺序。
3. 内嵌 Web 服务器的启动
Spring Boot 支持多种内嵌的 Web 服务器,如 Tomcat、Jetty 和 Undertow。默认情况下,Spring Boot 使用内嵌的 Tomcat 服务器,但开发者可以通过修改配置或依赖来切换服务器类型。
- Tomcat 启动过程:当使用内嵌 Tomcat 时,
SpringBootServletInitializer
会自动配置 Tomcat 的各项参数,如端口、上下文路径等。随后,TomcatWebServer
会被创建并启动,它会绑定到一个端口并开始监听 HTTP 请求。
- Servlet 注册:在应用启动时,Spring Boot 会自动注册 Web 应用所需的
Servlet
,Filter
和Listener
,这些组件被包装在SpringServletContainerInitializer
中并通过 SPI 机制加载。
- Web 应用上下文的初始化:在 Web 应用的上下文初始化过程中,Spring Boot 会加载
DispatcherServlet
,这是 Spring MVC 的核心调度器。所有进入的 HTTP 请求都会通过这个 Servlet 进行分发处理。
4. SpringApplication 的扩展点
Spring Boot 提供了多个扩展点,允许开发者在应用启动的不同阶段插入自定义的逻辑:
ApplicationContextInitializer
:它在ApplicationContext
刷新之前被调用,可以用来在应用上下文加载之前对其进行配置。
ApplicationListener
:它可以监听应用程序生命周期中的各种事件,如ApplicationStartingEvent
,ApplicationEnvironmentPreparedEvent
,ApplicationPreparedEvent
,ApplicationStartedEvent
和ApplicationReadyEvent
等。
SpringApplicationRunListeners
:这些监听器在SpringApplication
启动的早期阶段被调用,可以用来监视整个启动过程。
CommandLineRunner
和ApplicationRunner
:它们用于在应用启动完成后立即执行代码,非常适合执行一些启动后的初始化任务。
三、Spring Boot 启动优化策略
尽管 Spring Boot 极大简化了应用的启动过程,但在某些情况下,优化启动性能也是必要的,特别是在应用规模较大或启动时间要求较高时。以下是一些常见的优化策略:
1. 延迟加载 Bean
通过设置
@Lazy
注解,可以延迟 Bean 的加载,只有在第一次使用时才进行初始化。这可以减少启动时的内存占用和 CPU 消耗。2. 减少自动配置的范围
使用
@SpringBootApplication(exclude = { ... })
或 @EnableAutoConfiguration(exclude = { ... })
来排除不必要的自动配置类,以减少启动时间。3. 配置文件优化
尽量精简
application.properties
或 application.yml
配置文件,只保留必要的配置项,避免加载不需要的配置和资源。4. 内存和垃圾回收调优
在大规模应用中,调整 JVM 的堆内存大小和垃圾回收策略(如使用 G1 GC)可以提升启动性能。
5. 并行加载
Spring Boot 3.0 引入了并行加载机制,可以在
ApplicationContext
初始化过程中并行加载 Bean,以缩短启动时间。四、结论
Spring Boot 的启动机制展示了其强大的自动配置能力和简化开发的设计理念。从
SpringApplication.run()
方法开始,到内嵌 Web 服务器的启动,再到自动配置的应用和扩展点的使用,Spring Boot 的启动过程复杂而又灵活,为开发者提供了极大的便利性。通过深入理解 Spring Boot 的启动机制,开发者不仅可以更好地掌握这个框架,还能通过优化启动流程来提高应用的性能和响应速度。在实际开发中,掌握这些机制将有助于更高效地构建和部署生产级别的 Spring 应用程序。
- 作者:奥利弗
- 链接:https://www.aolifu.org/article/springboot_start
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
相关文章