Spring Boot 应用程序生命周期扩展点妙用

news2024/9/23 12:26:02

文章目录

  • 前言
  • 1. 应用程序生命周期扩展点
  • 2. 使用场景示例
    • 2.1 SpringApplicationRunListener
    • 2.2 ApplicationEnvironmentPreparedEvent
    • 2.3 ApplicationPreparedEvent
    • 2.4 ApplicationStartedEvent
    • 2.5 ApplicationReadyEvent
    • 2.6 ApplicationFailedEvent
    • 2.7 ApplicationRunner
  • 3. 参考文档

前言

上一篇我们着重按照分类讲解了一下Spring Boot的常见扩展点,接下来我们讲解一下Spring Boot 的应用程序生命周期扩展点的一些妙用。

Spring Boot的应用程序生命周期扩展点是一些接口,可以让开发者在应用程序的不同生命周期阶段插入自己的逻辑。这些扩展点可以帮助开发者在应用程序启动、关闭、重启等阶段执行一些额外的操作。

下面介绍几个常用的应用程序生命周期扩展点:

  1. ApplicationRunner和CommandLineRunner:这两个接口可以在应用程序启动完成后执行一些初始化的操作。例如,你可以实现一个ApplicationRunner来初始化数据库连接池,或者实现一个CommandLineRunner来加载一些初始化数据。

  2. ApplicationPreparedEvent:这个事件在应用程序准备启动时触发,可以在其中执行一些准备工作。例如,你可以监听这个事件,然后在应用程序启动之前执行一些配置文件的加载操作。

  3. ApplicationStartedEvent:这个事件在应用程序开始启动时触发,可以在其中执行一些初始化的操作。例如,你可以监听这个事件,然后在应用程序启动之前执行一些初始化的逻辑。

  4. ApplicationReadyEvent:这个事件在应用程序完全启动后触发,可以在其中执行一些额外的初始化操作。例如,你可以监听这个事件,然后在应用程序启动之后执行一些数据缓存的加载操作。

  5. ApplicationFailedEvent:这个事件在应用程序启动失败时触发,可以在其中执行一些错误处理的逻辑。例如,你可以监听这个事件,然后在应用程序启动失败时发送一封错误报告邮件。

通过实现这些扩展点,你可以在应用程序的不同生命周期阶段插入自己的逻辑,并且可以方便地扩展和定制应用程序的行为。这些扩展点的使用可以帮助你更好地管理和控制应用程序的生命周期,提高应用程序的可靠性和可维护性。

还是那句老话,这个不是八股文,只有知道才遇到相似场景的才能知道怎么用。学以致用,是我们分享内容的不变的宗旨
在这里插入图片描述

冰点出品,必属精品


1. 应用程序生命周期扩展点

应用程序生命周期扩展点是指在Spring Boot应用程序的生命周期中,提供了一系列的扩展点,开发人员可以通过实现这些扩展点来对应用程序的生命周期进行控制和定制。这些扩展点主要包括以下几个:
在这里插入图片描述
此图来自网络

2. 使用场景示例

2.1 SpringApplicationRunListener

它是一个监听器接口,用于在Spring应用程序的运行生命周期中监听和响应相关事件。可以通过实现该接口来自定义应用程序的启动和关闭行为。
好的,让我们来看一个使用SpringApplicationRunListener的例子。

假设你正在开发一个在线学习平台的后端系统。在应用程序启动时,你想要执行一些特定的操作,例如加载配置文件、初始化数据库连接等。这时候,你可以使用SpringApplicationRunListener来监听应用程序的启动事件,并在事件触发时执行这些操作。

首先,需要创建一个名为CustomSpringApplicationRunListener的类,实现SpringApplicationRunListener接口,并重写相应的方法。CustomSpringApplicationRunListener类实现了SpringApplicationRunListener接口的各个方法。你可以根据需要在这些方法中执行特定的操作。例如,在starting方法中,你可以执行启动前的操作,如加载配置文件;在started方法中,你可以执行应用程序已启动的操作,如启动后台任务等。

import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringApplicationRunListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;

public class CustomSpringApplicationRunListener implements SpringApplicationRunListener {

    public CustomSpringApplicationRunListener(SpringApplication application, String[] args) {
    }

    @Override
    public void starting() {
        System.out.println("Application starting...");
        // 执行启动前的操作,如加载配置文件等
    }

    @Override
    public void environmentPrepared(ConfigurableEnvironment environment) {
        System.out.println("Environment prepared...");
        // 执行环境准备的操作,如设置环境变量等
    }

    @Override
    public void contextPrepared(ConfigurableApplicationContext context) {
        System.out.println("Context prepared...");
        // 执行上下文准备的操作,如初始化数据库连接等
    }

    @Override
    public void contextLoaded(ConfigurableApplicationContext context) {
        System.out.println("Context loaded...");
        // 执行上下文加载的操作,如配置Bean等
    }

    @Override
    public void started(ConfigurableApplicationContext context) {
        System.out.println("Application started...");
        // 执行应用程序已启动的操作,如启动后台任务等
    }

    @Override
    public void running(ConfigurableApplicationContext context) {
        System.out.println("Application running...");
        // 执行应用程序运行的操作,如执行定时任务等
    }

    @Override
    public void failed(ConfigurableApplicationContext context, Throwable exception) {
        System.out.println("Application failed to start...");
        // 执行应用程序启动失败的操作,如记录错误日志等
    }
}

接下来,需要在应用程序的META-INF目录下创建一个名为spring.factories的文件,并在其中配置CustomSpringApplicationRunListener类。

org.springframework.boot.SpringApplicationRunListener=com.example.CustomSpringApplicationRunListener

这样,当你的应用程序启动时,Spring Boot将会自动创建CustomSpringApplicationRunListener实例,并在适当的时机调用对应的方法。

这只是一个简单的例子,展示了如何使用SpringApplicationRunListener接口来监听应用程序的启动事件,并在事件触发时执行特定的操作 。实际项目可能需要考虑的问题更多,比如加载顺序,依赖关系等等。

2.2 ApplicationEnvironmentPreparedEvent

该事件在应用程序启动前触发,用于在环境准备阶段执行一些操作,例如:加载配置文件、设置系统属性等。
当应用程序的环境准备就绪时,可以使用ApplicationEnvironmentPreparedEvent来执行某些操作。例如,假设你正在开发一个基于Spring Boot的社交媒体应用程序,你可以使用这个事件来加载特定环境的配置文件,以便根据不同的环境配置进行不同的操作。

在这个例子中,我们可以通过创建一个实现了ApplicationListener接口的类来监听ApplicationEnvironmentPreparedEvent事件。然后在onApplicationEvent方法中,我们可以根据当前的环境配置加载不同的配置文件。可能举的事例不是很合理,大家能够理解就OK。

import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
import org.springframework.context.ApplicationListener;

public class EnvironmentPreparedListener implements ApplicationListener<ApplicationEnvironmentPreparedEvent> {

    @Override
    public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {
        String environment = event.getEnvironment().getActiveProfiles()[0];
        
        // 根据环境配置加载不同的配置文件
        if (environment.equals("dev")) {
            // 加载dev环境的配置文件
        } else if (environment.equals("prod")) {
            // 加载prod环境的配置文件
        } else if (environment.equals("windows")) {
            // 加载prod环境的配置文件
        } else if (environment.equals("linux")) {
            // 加载prod环境的配置文件
        }
        
        // 执行其他操作
    }
}

在Spring Boot应用程序的入口类中,我们可以将这个监听器注册到Spring容器中:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SocialMediaApplication {

    public static void main(String[] args) {
        SpringApplication application = new SpringApplication(SocialMediaApplication.class);
        application.addListeners(new EnvironmentPreparedListener());
        application.run(args);
    }
}

这样,当应用程序的环境准备就绪时,EnvironmentPreparedListener中的onApplicationEvent方法将会被触发,你可以在该方法中执行一些特定于环境配置的操作,例如加载特定的配置文件。这在开发和部署应用程序时非常有用,可以根据不同的环境配置进行不同的初始化操作。

2.3 ApplicationPreparedEvent

该事件在应用程序上下文创建完成后触发,用于在应用程序准备阶段执行一些操作,例如:创建和初始化Bean等。

好的,我可以举一个使用ApplicationPreparedEvent的例子。

假设你正在开发一个电子商务网站的后端系统,当应用程序启动时,你希望自动初始化一些商户数据到缓存中。

首先,你需要创建一个实现ApplicationListener接口的类,用于监听ApplicationPreparedEvent事件。例如,你可以创建一个名为DataInitializationListener的类:

import org.springframework.boot.context.event.ApplicationPreparedEvent;
import org.springframework.context.ApplicationListener;

public class DataInitializationListener implements ApplicationListener<ApplicationPreparedEvent> {

    @Override
    public void onApplicationEvent(ApplicationPreparedEvent event) {
        // 在应用程序准备阶段执行初始化数据的操作
        initializeData();
    }

    private void initializeData() {
        // 在这里执行初始化数据的逻辑,例如将商户数据加载到缓存中去
        // ...
    }
}

然后,在你的Spring Boot应用程序的主类中,将DataInitializationListener注册为一个bean,以便在应用程序启动时被自动调用:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class YourApplication {

    public static void main(String[] args) {
        SpringApplication.run(YourApplication.class, args);
    }

    @Bean
    public DataInitializationListener dataInitializationListener() {
        return new DataInitializationListener();
    }
}

现在, 运行应用程序时,DataInitializationListener将会监听ApplicationPreparedEvent事件,并在应用程序准备阶段执行initializeData方法,从而实现自动初始化商户数据的功能。

ApplicationPreparedEvent事件是在应用程序准备阶段触发的,该阶段是在ApplicationContext创建之前,但已经加载了bean定义。因此,你可以在该事件中执行与应用程序初始化相关的操作。

2.4 ApplicationStartedEvent

该事件在应用程序启动完成后触发,用于在应用程序启动后执行一些操作,例如:向日志中输出启动信息等。

2.5 ApplicationReadyEvent

该事件在应用程序准备就绪后触发,用于在应用程序运行期间执行一些操作,例如:启动定时任务、初始化缓存等。

2.6 ApplicationFailedEvent

该事件在应用程序启动失败后触发,用于在应用程序启动失败时执行一些操作,例如:记录日志、发送告警等。

当应用程序启动失败时,可以使用ApplicationFailedEvent事件来发送通知或记录日志,以便进行故障排查和问题解决。例如,假设我们的应用程序依赖于数据库连接,如果数据库连接失败导致应用程序无法启动,我们可以创建一个监听器类来处理这种情况。下面是一个简单的例子:

创建一个实现ApplicationListener接口的监听器类,例如ApplicationFailedListener:

import org.springframework.boot.context.event.ApplicationFailedEvent;
import org.springframework.context.ApplicationListener;

public class ApplicationFailedListener implements ApplicationListener<ApplicationFailedEvent> {

    @Override
    public void onApplicationEvent(ApplicationFailedEvent event) {
        // 获取失败的异常信息
        Throwable throwable = event.getException();
        
        // 发送通知或记录日志,进行故障排查和问题解决
        System.out.println("应用程序启动失败:" + throwable.getMessage());
    }
}

然后,在Spring Boot应用程序的入口类中,将该监听器类注册为一个Bean:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);

        // 其他应用程序逻辑
    }

    @Bean
    public ApplicationFailedListener applicationFailedListener() {
        return new ApplicationFailedListener();
    }
}

现在,当应用程序启动失败时,ApplicationFailedListener监听器中的onApplicationEvent方法将被调用,并打印出失败的异常信息。

这个例子只是一个简单的示例,你可以根据实际需求进行扩展和定制化。你可以根据具体的业务场景,使用该事件来发送邮件、短信通知、记录日志或进行其他故障处理操作。

2.7 ApplicationRunner

可以利用ApplicationRunner接口来执行一些应用程序启动后的初始化任务。

@Component
public class MyApplicationRunner implements ApplicationRunner {

    @Override
    public void run(ApplicationArguments args) throws Exception {
        // 在应用程序启动后执行的任务
        System.out.println("应用程序启动后执行的任务");
        // 可以在这里执行一些初始化操作,如加载配置文件、初始化数据库连接等
    }
}

我们创建了一个名为MyApplicationRunner的类,并实现了ApplicationRunner接口。在类中,我们重写了run方法,该方法会在应用程序启动后被自动调用。在run方法中,可以编写需要在应用程序启动后执行的任务。例如,可以在这里加载配置文件、初始化数据库连接、创建一些初始数据等。

要让Spring Boot应用程序自动执行该任务,需要将MyApplicationRunner类注解为一个@Component或者@Service等Spring Bean,并将其注册到Spring容器中。这样,当应用程序启动时,Spring Boot会自动调用MyApplicationRunner的run方法。

这样 也就可以利用ApplicationRunner接口来执行一些应用程序启动后的初始化任务。

3. 参考文档

  1. Spring Boot官方文档:https://spring.io/projects/spring-boot
  2. Spring Boot Reference Guide:https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/
  3. Spring Boot官方文档相关 https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-customizing-bean-definitions
  4. Spring Boot 自动配置 https://docs.spring.io/spring-boot/docs/3.1.2/reference/html/auto-configuration-classes.html#appendix.auto-configuration-classes

在这里插入图片描述

👏好了,本次的Spring Boot 的扩展点分享就到这儿,我是冰点,下次见。如果我的文章对你有所收获,可以给个赞。如果有疑问可以在评论区留言。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/801542.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

产品能力|AIRIOT可视化组态引擎如何应用于物联业务场景中

在物联网的业务应用场景中&#xff0c;可视化组态是一个必不可少的功能需求。不同的行业场景&#xff0c;都需要将物联设备采集的数据和业务场景状态进行直观的可视化展示&#xff0c;供使用者进行分析或决策。如工艺流程用能监测、3D场景构建、能耗趋势场景报警联动、重点设备…

RAD-NeRF模型

问题1&#xff1a; 添加在以下的参数里添加bin_size0 问题2&#xff1a; 更行GLIBC_2.29_glibc_2_29.so_xihuanyuye的博客-CSDN博客

如何使用Crank给我们的类库做基准测试

背景 当我们写了一个类库提供给别人使用时&#xff0c;我们可能会对它做一些基准测试来测试一下它的性能指标&#xff0c;好比内存分配等。 在 .NET 的世界中&#xff0c;用 BenchmarkDotNet 来做这件事是非常不错的选择&#xff0c;我们只要写少量的代码就可以在本地运行基准…

【小白必看】Python爬取NBA球员数据示例

文章目录 前言导入需要的库和模块设置请求头和请求地址发送HTTP请求并获取响应处理响应结果解析数据将结果保存到文件完整代码详细解析 运行效果结束语 前言 使用 Python 爬取 NBA 球员数据的示例代码。通过发送 HTTP 请求&#xff0c;解析 HTML 页面&#xff0c;然后提取出需要…

imgcat命令行查看图片

背景 昨天在哔哩哔哩上看到了mac控制台工具imgcat 可以实现在控制台查看图片&#xff0c;我觉得太酷炫了&#xff01;于是手动的安利一下。 下载工具 curl "https://iterm2.com/utilities/imgcat" > imgcat执行权限 chmod x imgcat第一次使用 ./imgcat ~/img…

RocketMQ发送消息还有这种坑?遇到SYSTEM_BUSY不重试?

这里是weihubeats,觉得文章不错可以关注公众号小奏技术&#xff0c;文章首发。拒绝营销号&#xff0c;拒绝标题党 RocketMQ版本 5.1.0 背景 最近线上的RocketMQ集群遇到了如下问题&#xff0c;业务方的小伙伴反馈问题&#xff0c;说出现了 MQBrokerException&#xff1a;CO…

C++数据结构笔记(10)递归实现二叉树的三序遍历

对于三种遍历方式来说&#xff0c;均为先左后右&#xff01;区别在于根结点的位置顺序 先序遍历&#xff1a;根——左——右 中序遍历&#xff1a;左——根——右 后序遍历&#xff1a;左——右——根 &#xff08;所谓先中后的顺序&#xff0c;是指根结点D先于子树还是后于…

力扣算法练习(四)

1.盛水最多的容器(11) 给定一个长度为 n 的整数数组 height 。有 n 条垂线&#xff0c;第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 找出其中的两条线&#xff0c;使得它们与 x 轴共同构成的容器可以容纳最多的水。 返回容器可以储存的最大水量。 说明&#xff1a;…

Vue 常用指令 v-on 自定义参数和事件修饰符

自定义参数就是可以在触发事件的时候传入自定义的值。 文本框&#xff0c;绑定了一个按钮事件&#xff0c;对应的逻辑是sayhi&#xff0c;现在无论按下什么按钮都会触发这个sayhi。但是实际上不是所有的按钮都会触发&#xff0c;只会限定某一些按钮&#xff0c;最常见的按钮就…

linux下nginx的安装和使用

文章目录 &#x1f4d2;安装nginx1️⃣上传到对应目录2️⃣解压nginx3️⃣检查是否启动成功 &#x1f4d2;使用nginx1️⃣简单的反向代理2️⃣介绍location配置中root和alias的区别 &#x1f4d2;安装nginx 官网下载: https://nginx.org/ 我这里自己下载的是稳定版本 nginx-1.…

手撕顺序表

> 作者简介&#xff1a;დ旧言~&#xff0c;目前大一&#xff0c;现在学习Java&#xff0c;c&#xff0c;c&#xff0c;Python等 > 座右铭&#xff1a;松树千年终是朽&#xff0c;槿花一日自为荣。 > 望小伙伴们点赞&#x1f44d;收藏✨加关注哟&#x1f495;&#x1…

标准IO_文件读写_fgetc,getchar,ungetc,fgets,fputs,fread,fwrite

目录 1.单字符文件读写 1.1 单字符读文件 1.1.1 fgetc函数 1.1.2 getc函数 1.1.3 getchar函数 1.1.4 ungetc函数 1.1.5 单字符读文件综合示例代码 1.2 单字符写文件 1.2.1 fputc函数 1.2.2 putc函数 1.2.3 putchar函数 1.2.4 单字符写文件综合示例代码 2.多字符文…

c++11 标准模板(STL)(std::basic_filebuf)(七)

定义于头文件 <fstream> template< class CharT, class Traits std::char_traits<CharT> > class basic_filebuf : public std::basic_streambuf<CharT, Traits> std::basic_filebuf 是关联字符序列为文件的 std::basic_streambuf 。输入序…

python核心-面向对象-三大特性:封装,继承,多态

封装 继承 # class Animal: # pass # # class xxx: # pass # # class Dog(Animal,xxx): # pass # # # d Dog() # print(d.__class__) # print(Dog.__class__) # # # print(Dog.__bases__) # print(Animal.__bases__) # # object# ---------------------继承-资源…

最小环计数

Problem - 7322 思路&#xff1a;跑一个floyd&#xff0c;同时求出最小环以及进行最小环计数&#xff0c;对于每个环&#xff0c;我们每次用编号最大的点进行统计&#xff0c;防止重复 以下是模板 for(int k1;k<n;k) {for(int i1;i<n;i) {for(int j1;j<n;j) {if(dis…

java快速生成数据库表文档(HTML、DOC、MD)

在企业级开发中、我们经常会有编写数据库表结构文档的时间付出&#xff0c;关于数据库表结构文档状态&#xff1a;要么没有、要么有、但都是手写、后期运维开发&#xff0c;需要手动进行维护到文档中&#xff0c;很是繁琐&#xff0c;这里推荐一个开源项目&#xff1a;screw gi…

读数据压缩入门笔记09_多媒体数据压缩

1. 压缩分类 1.1. 多媒体数据压缩&#xff08;media-specific compression&#xff09; 1.2. 通用压缩&#xff08;general purpose compression&#xff09; 2. 有损压缩算法 2.1. 为了使数据压缩得更小&#xff0c;可以牺牲多媒体的质量这样的数据转换 2.2. 针对特定的多…

Kaggle灾难推文的自然语言处理-最佳得分详解

目录 灾难推文的自然语言处理——预测哪些推文是关于真实灾难的&#xff0c;哪些不是。 一、比赛概述 二、数据集 三、代码 0.导入库与数据 1. 关键字和位置 1.1 缺失值 1.2 元素和目标分布 2. 元特征 3. 目标和N-grams 3.1 目标 3.2 unigrams 一元语法 3.3 big…

[回馈]ASP.NET Core MVC开发实战之商城系统(三)

经过一段时间的准备&#xff0c;新的一期【ASP.NET Core MVC开发实战之商城系统】已经开始&#xff0c;在之前的文章中&#xff0c;讲解了商城系统的整体功能设计&#xff0c;页面布局设计&#xff0c;环境搭建&#xff0c;系统配置&#xff0c;及首页【商品类型&#xff0c;ba…

如何使用ArcGIS Pro制作越来越真实的水域效果

制图的目的就是为了让图更加的美观&#xff0c;这里我们以水域效果为例&#xff0c;为大家讲解一下如何一步步制作越来越真实的水域效果&#xff0c;希望能对你有所帮助。 常规效果 使用过ArcMap制图的朋友应该比较熟悉&#xff0c;可以在符号系统内修改一下填充颜色&#xff…