Spring Boot 的生命周期

ops/2024/11/14 15:07:05/

        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> {@Overridepublic 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 {@Overridepublic void run(ApplicationArguments args) throws Exception {// 启动后的初始化任务}
}@Component
public class MyCommandLineRunner implements CommandLineRunner {@Overridepublic 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> {@Overridepublic 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) {// 构造函数}@Overridepublic void starting() {// 应用启动前}@Overridepublic void environmentPrepared(ConfigurableEnvironment environment) {// 环境准备完成后}@Overridepublic void contextPrepared(ConfigurableApplicationContext context) {// 上下文准备完成后}@Overridepublic void contextLoaded(ConfigurableApplicationContext context) {// 上下文加载完成后}@Overridepublic void started(ConfigurableApplicationContext context) {// 应用启动完成后}@Overridepublic void running(ConfigurableApplicationContext context) {// 应用运行中}@Overridepublic void failed(ConfigurableApplicationContext context, Throwable exception) {// 应用启动失败}
}

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


http://www.ppmy.cn/ops/133334.html

相关文章

雷光联动自动化标校方法

技术领域 本发明涉及光电技术领域,安防领域,尤其涉及雷达光电动态标校等。 背景技术 随着雷达与光电的应用领域越来越广泛,如重点区域防护,“低慢小”目标探测,船只探测,鸟类探测等。其使用领域,用途日趋多样化,但在应用中有个难度较大的流程就是实现雷达与光电的零…

练习LabVIEW第四十三题

学习目标&#xff1a; 模拟红绿灯&#xff0c;红灯亮十秒&#xff0c;绿灯亮五秒&#xff0c;交替&#xff0c;并用波形图将波形显示 开始编写&#xff1a; 前面板 两个指示灯&#xff0c;一个红色&#xff0c;一个绿色&#xff0c;一个波形图&#xff1b; 程序框图 创建…

SDL事件相关

文章目录 事件相关的函数和数据结构用户自定义事件代码相关&#xff1a; 事件相关的函数和数据结构 SDL_WaitEvent :等待一个事件SDL_PushEvent 发送一个事件SDL_PumpEvents(): 将硬件设备产生的时间放入事件队列 &#xff0c;用于读取事件&#xff0c;在调用该函数之前&#…

阿里云aliyun gradle安装包下载地址

阿里云 查找你要下载的安装包 macports-distfiles-gradle安装包下载_开源镜像站-阿里云 https://mirrors.aliyun.com/macports/distfiles/gradle/gradle-8.9-bin.zip 腾讯 https://mirrors.cloud.tencent.com/gradle/ https://mirrors.cloud.tencent.com/gradle/ https…

学校服务器连接pycharm配置2

上一个可能还是有点问题&#xff0c;因为实际在跑的时候读取的其实是本地的anaconda&#xff0c;这个重新整了一下流程 首先在学校服务器先激活自己创建的虚拟环境&#xff0c;这里就不截图了 然后在pycharm里面打开设置 选择这个python解释器 这里有添加解释器 选择SSH …

机器学习-35-提取时间序列信号的特征

文章目录 1 特征提取方法1.1 特征提取过程1.2 两类特征提取方法2 基于数据驱动的方法2.1 领域特定特征提取2.2 基于频率的特征提取2.2.1 模拟信号2.2.2 傅里叶变换2.2.3 抽取最大幅值对应特征2.2.4 抽取峰值幅值对应特征2.3 基于统计的特征提取2.4 基于时间的特征提取3 参考附录…

36.Redis核心设计原理

本文针对前面的讲解做一次总结 1.Redis基本特性 1.非关系型的键值对数据库&#xff0c;可以根据键以O(1)的时间复杂度取出或插入关联值 2.Redis的数据是存在内存中的 3.键值对中键的类型可以是字符串&#xff0c;整型&#xff0c;浮点型等&#xff0c;且键是唯一的 4.键值对中…

企业数字化转型的进化之路:认清3个阶段、把握5个环节!

数字化转型并不是简单的技术堆砌&#xff0c;而是需要企业对其核心业务进行深度洞察和重新设计。企业不应该盲目追随技术潮流&#xff0c;而是要依据自身的实际情况和持续增长的需求&#xff0c;有策略地选择适合自己的转型路径。 对此&#xff0c;本文将从企业数字化转型定义…