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

文章目录

  • 前言
  • 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) {}@Overridepublic void starting() {System.out.println("Application starting...");// 执行启动前的操作,如加载配置文件等}@Overridepublic void environmentPrepared(ConfigurableEnvironment environment) {System.out.println("Environment prepared...");// 执行环境准备的操作,如设置环境变量等}@Overridepublic void contextPrepared(ConfigurableApplicationContext context) {System.out.println("Context prepared...");// 执行上下文准备的操作,如初始化数据库连接等}@Overridepublic void contextLoaded(ConfigurableApplicationContext context) {System.out.println("Context loaded...");// 执行上下文加载的操作,如配置Bean等}@Overridepublic void started(ConfigurableApplicationContext context) {System.out.println("Application started...");// 执行应用程序已启动的操作,如启动后台任务等}@Overridepublic void running(ConfigurableApplicationContext context) {System.out.println("Application running...");// 执行应用程序运行的操作,如执行定时任务等}@Overridepublic 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> {@Overridepublic 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> {@Overridepublic 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);}@Beanpublic 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> {@Overridepublic 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);// 其他应用程序逻辑}@Beanpublic ApplicationFailedListener applicationFailedListener() {return new ApplicationFailedListener();}
}

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

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

2.7 ApplicationRunner

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

@Component
public class MyApplicationRunner implements ApplicationRunner {@Overridepublic 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.mzph.cn/news/19284.shtml

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

相关文章

虚拟机之间配置免密登录

目录 一、配置主机名映射 二、虚拟机配置SSH免密登录 三、验证 一、配置主机名映射 即修改/etc/hosts文件&#xff0c;将几台服务器和主机名进行映射。 注意每台服务器都要进行同样的配置。这样在各自服务器下&#xff0c;我们就可以通过主机名访问对应的ip地址了。 当然&…

BGP属性+选路规则

目录 一&#xff0c;BGP的属性—基础属性 1.PrefVal 2.LocPrf 3、优先本地下一跳 &#xff08;NextHop&#xff09; 4、AS-PATH 5、起源属性 6、MED -多出口鉴别属性 二&#xff0c;BGP选路规则 三&#xff0c;BGP的社团属性 一&#xff0c;BGP的属性—基础…

低碳 Web 实践指南

现状和问题 2023年7月6日&#xff0c;世界迎来有记录以来最热的一天。气候变化是如今人类面临的最大健康威胁。据世界卫生组织预测2030年至2050年期间&#xff0c;气候变化预计每年将造成约25万人死亡。这是人们可以真切感受到的变化&#xff0c;而背后的主要推手是碳排放。 …

功率放大器的种类有哪三种类型

功率放大器是一种能将输入信号转换为更高功率输出的电子设备。在电子工程和音频领域中&#xff0c;功率放大器通常被分为三种类型&#xff1a;A类、B类和AB类。下面安泰电子将详细介绍这三种类型的功率放大器及其特点。 A类功率放大器 A类功率放大器是一种基本的线性功率放大器…

Flask简介与基础入门

一、了解框架 Flask作为Web框架&#xff0c;它的作用主要是为了开发Web应用程序。那么我们首先来了解下Web应用程序。Web应用程序 (World Wide Web)诞生最初的目的&#xff0c;是为了利用互联网交流工作文档。 1、一切从客户端发起请求开始。 所有Flask程序都必须创建一个程序…

【电网技术复现】考虑实时市场联动的电力零售商鲁棒定价策略(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

代码随想录算法训练营之JAVA|第十八天| 235. 二叉搜索树的最近公共祖先

今天是第 天刷leetcode&#xff0c;立个flag&#xff0c;打卡60天&#xff0c;如果做不到&#xff0c;完成一件评论区点赞最高的挑战。 算法挑战链接 235. 二叉搜索树的最近公共祖先https://leetcode.cn/problems/lowest-common-ancestor-of-a-binary-search-tree/descriptio…

sql 参数自动替换

需求&#xff1a;看日志时&#xff0c;有的sql 非常的长&#xff0c;参数比较多&#xff0c;无法直接在sql 客户端工具执行&#xff0c;如果一个一个的把问号占位符替换为参数太麻烦&#xff0c;因此写个html 小工具&#xff0c;批量替换&#xff1a; 代码&#xff1a; <!…

从零开始学python(十四)百万高性能框架scrapy框架

前言 回顾之前讲述了python语法编程 必修入门基础和网络编程&#xff0c;多线程/多进程/协程等方面的内容&#xff0c;后续讲到了数据库编程篇MySQL&#xff0c;Redis&#xff0c;MongoDB篇&#xff0c;和机器学习&#xff0c;全栈开发&#xff0c;数据分析&#xff0c;爬虫数…

Java多线程面试21题

并行和并发有什么区别&#xff1f; 并行是指两个或者多个事件在同一时刻发生&#xff1b;而并发是指两个或多个事件在同一时间间隔发生。 并行是在不同实体上的多个事件&#xff0c;并发是在同一实体上的多个事件。 在一台处理器上“同时”处理多个任务&#xff0c;在多台处理…

C++多线程环境下的单例类对象创建

使用C无锁编程实现多线程下的单例模式 贺志国 2023.8.1 一、尺寸较小的类单例对象创建 如果待创建的单例类SingletonForMultithread内包含的成员变量较少&#xff0c;整个类占用的内存空间较小&#xff0c;则可以使用如下方法来创建单例对象&#xff08;如果类的尺寸较大&am…

新SDK平台下载开源全志D1-H/D1s的SDK

获取SDK SDK 使用 Repo 工具管理&#xff0c;拉取 SDK 需要配置安装 Repo 工具。 Repo is a tool built on top of Git. Repo helps manage many Git repositories, does the uploads to revision control systems, and automates parts of the development workflow. Repo is…

C语言的转义字符

转义字符也叫转移序列&#xff0c;包含如下&#xff1a; 转移序列 \0oo 和 \xhh 是 ASCII 码的特殊表示。 八进制数示例&#xff1a; 代码&#xff1a; #include<stdio.h> int main(void) {char beep\007;printf("%c\n",beep);return 0; }结果&#xff1a; …

机器视觉初步14:相机标定原理及应用

相机标定是指通过已知的相机参数&#xff0c;解算相机内部参数矩阵和外部参数矩阵。 文章目录 1.为什么要标定&#xff1f;2.工业场景中常见的标定方法2.1. 使用棋盘格标定板&#xff08;Checkerboard Markers&#xff09;2.2 使用相机自标定2.3. 使用三维物体标定2.4.九孔标…

【Linux】—— 进程的创建和退出

序言&#xff1a; 在上期&#xff0c;我们已经对 Linux的进程的相关知识进行了相关的学习。接下来&#xff0c;我们要学习的便是关于进程控制 的基本知识&#xff01;&#xff01;&#xff01; 目录 &#xff08;一&#xff09;进程创建 1、fork函数初识 2、写时拷贝 3、f…

Docker中容器数据卷

容器数据卷 一.什么是容器数据卷二.使用数据卷方式一&#xff1a;直接使用命令来挂载 -v 三.具名和匿名挂载 一.什么是容器数据卷 docker理念 将应用和环境打包成一个镜像&#xff01; 数据&#xff1f;如果数据都在容器中&#xff0c;那么我们的容器删除&#xff0c;数据就会…

oracle 19c打补丁遭遇OPATCHAUTO-72043OPATCHAUTO-68061

最近&#xff0c;在AIX上的新装oracle 19C数据库基础版本&#xff0c;使用opatchauto打PSU补丁集35037840时遇到了OPATCHAUTO-72043报错&#xff0c;无法正常应用GI补丁。 一、环境描述 操作系统&#xff1a;AIX 数据库版本&#xff1a;oracle rac 19.3.0新装基础版 应用PS…

2023拒绝内卷!两年转行网络安全真实看法!

我目前转行网络安全两年&#xff0c;没啥天分&#xff0c;全靠努力&#xff0c;基本能够得上中级的水平了。看到大家对转行网络安全挺感兴趣&#xff0c;也有挺多争议&#xff0c;想把我的建议和经验告诉大家。 有很多人觉得网络安全已经饱和了&#xff0c;现在选择这个工作&a…

Spring Boot : ORM 框架 JPA 与连接池 Hikari

数据库方面我们选用 Mysql &#xff0c; Spring Boot 提供了直接使用 JDBC 的方式连接数据库&#xff0c;毕竟使用 JDBC 并不是很方便&#xff0c;需要我们自己写更多的代码才能使用&#xff0c;一般而言在 Spring Boot 中我们常用的 ORM 框架有 JPA 和 Mybaties &#xff0c;本…

面试之多线程案例(四)

1.单例模式 单例模式是指在内存中只会创建且仅创建一次对象的设计模式。在程序中多次使用同一个对象且作用相同时&#xff0c;为了防止频繁地创建对象使得内存飙升&#xff0c;单例模式可以让程序仅在内存中创建一个对象&#xff0c;让所有需要调用的地方都共享这一单例对象。…