Spring Boot的生命周期非常丰富,包含了从初始化到运行再到关闭的各个阶段。每个阶段都有其特定的任务和事件,开发者可以利用这些生命周期的特性来更好地控制应用的行为。
初始化阶段 (Initialization Phase)
1. 构造 SpringApplication
对象
当调用 SpringApplication.run(...)
方法时,Spring Boot 会创建一个 SpringApplication
实例。这个实例是整个应用启动的核心。以下是创建 SpringApplication
实例的代码:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MyApp {
public static void main(String[] args) {
SpringApplication.run(MyApp.class, args);
}
}
1.1 配置 SpringApplication
对象
SpringApplication
提供了许多配置选项,例如设置应用的名称、监听器、初始化器等。例如,可以设置应用的显示名称:
SpringApplication app = new SpringApplication(MyApp.class);
app.setBannerMode(Banner.Mode.OFF);
app.run(args);
1.2 准备环境
初始化环境变量:Spring Boot 会自动加载系统属性和环境变量。
创建 ConfigurableEnvironment
:创建一个 StandardEnvironment
对象,该对象负责加载 application.properties
或 application.yml
文件中的配置。
监听器初始化:Spring Boot 会初始化 SpringApplicationRunListener
,这些监听器会在应用的各个生命周期点被调用。
运行阶段 (Running Phase)
2. 创建 ApplicationContext
根据应用类型(Servlet, 响应式 Web 应用(Reactive)以及非 Web 应用(None)),Spring Boot 会选择合适的 ApplicationContext
类型。例如,对于 Web 应用,它会创建 AnnotationConfigServletWebServerApplicationContext
。
2.1 应用初始器
在 ApplicationContext
刷新之前,Spring Boot 会调用所有注册的 ApplicationContextInitializer
。开发者可以通过实现 ApplicationContextInitializer
接口来定制 ApplicationContext
的初始化过程。例如:
public class MyApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
// 自定义初始化逻辑
}
}
2.2 加载配置
加载主类:Spring Boot 会加载带有 @SpringBootApplication
注解的主类。
自动配置:通过 @EnableAutoConfiguration
注解,Spring Boot 会根据类路径中的依赖自动配置应用。
组件扫描:通过 @ComponentScan
注解,Spring Boot 会扫描并注册主类所在包及其子包下的所有组件。
2.3 刷新上下文
Bean 定义加载:Spring Boot 会加载所有的 Bean 定义,包括 XML 配置文件和注解配置。
Bean 实例化:实例化所有非懒加载的单例 Bean。
Bean 初始化:调用 Bean 的初始化方法(如 @PostConstruct
方法)。
Bean 后处理:执行 Bean 的后处理(如 BeanPostProcessor
)。
发布 ContextRefreshedEvent
:当 ApplicationContext
完成刷新时,会发布 ContextRefreshedEvent
事件。
2.4 启动 Web 服务器
如果是 Web 应用,Spring Boot 会启动嵌入式的 Web 服务器(例如 Tomcat、Jetty 或 Undertow)。例如,Tomcat 服务器的启动过程包括初始化 Servlet 容器、注册 Servlet 和 Filter、启动 HTTP 端口等。
2.5 执行 ApplicationRunner
和 CommandLineRunner
当 ApplicationContext
刷新完成后,Spring Boot 会查找并执行实现了 ApplicationRunner
和 CommandLineRunner
接口的 Bean。这些 Bean 通常用于执行启动后的初始化任务。例如:
@Component
public class MyApplicationRunner implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
// 启动后的初始化任务
}
}
@Component
public class MyCommandLineRunner implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
// 启动后的初始化任务
}
}
2.6 发布 ApplicationReadyEvent
当应用准备好接收流量时,Spring Boot 会发布 ApplicationReadyEvent
事件。这表明应用已经完全启动,并且可以处理外部请求。
结束阶段 (Shutdown Phase)
3. 应用关闭
关闭 Web 服务器:如果是 Web 应用,Spring Boot 会关闭嵌入式的 Web 服务器。
销毁 Bean:销毁所有的单例 Bean,调用 Bean 的销毁方法(如 @PreDestroy
方法)。
关闭 ApplicationContext
:调用 ApplicationContext
的 close
方法,发布 ContextClosedEvent
事件。
发布 ApplicationShutdownEvent
:发布应用关闭事件,通知监听器应用即将关闭。
生命周期事件 (Lifecycle Events)
Spring Boot 应用程序在其生命周期中会发布多个事件,开发者可以通过实现 ApplicationListener
接口来监听这些事件,并在事件发生时执行自定义逻辑。以下是一些重要的生命周期事件:
ApplicationStartingEvent
:应用启动时的第一个事件。
ApplicationEnvironmentPreparedEvent
:环境准备完成后触发。
ApplicationPreparedEvent
:应用上下文准备完成后触发。
ApplicationStartedEvent
:应用启动完成后触发。
ApplicationReadyEvent
:应用准备好接收请求时触发。
ApplicationFailedEvent
:应用启动失败时触发。
ContextRefreshedEvent
:应用上下文刷新完成后触发。
ContextClosedEvent
:应用上下文关闭时触发。
自定义生命周期行为
开发者可以通过实现 ApplicationListener
接口来监听上述事件,并在事件触发时执行自定义逻辑。例如,监听 ApplicationReadyEvent
事件:
@Component
public class MyApplicationReadyEventListener implements ApplicationListener<ApplicationReadyEvent> {
@Override
public void onApplicationEvent(ApplicationReadyEvent event) {
System.out.println("My application is now ready and running.");
// 可以在这里执行额外的初始化逻辑
}
}
此外,你还可以通过实现 SpringApplicationRunListener
接口来监听整个应用启动过程中的更多事件。例如:
public class MySpringApplicationRunListener implements SpringApplicationRunListener {
public MySpringApplicationRunListener(SpringApplication application, String[] args) {
// 构造函数
}
@Override
public void starting() {
// 应用启动前
}
@Override
public void environmentPrepared(ConfigurableEnvironment environment) {
// 环境准备完成后
}
@Override
public void contextPrepared(ConfigurableApplicationContext context) {
// 上下文准备完成后
}
@Override
public void contextLoaded(ConfigurableApplicationContext context) {
// 上下文加载完成后
}
@Override
public void started(ConfigurableApplicationContext context) {
// 应用启动完成后
}
@Override
public void running(ConfigurableApplicationContext context) {
// 应用运行中
}
@Override
public void failed(ConfigurableApplicationContext context, Throwable exception) {
// 应用启动失败
}
}
通过实现这些接口,开发者可以在应用的生命周期中插入自定义逻辑,以满足特定的需求。