Spring Boot 的生命周期

时间:2024-11-12 22:52:29

        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 会查找并执行实现了 ApplicationRunnerCommandLineRunner 接口的 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) {
        // 应用启动失败
    }
}

       通过实现这些接口,开发者可以在应用的生命周期中插入自定义逻辑,以满足特定的需求。