六种方式,教你在SpringBoot初始化时搞点事情!

前言

在实际工作中总是需要在项目启动时做一些初始化的操作,比如初始化线程池、提前加载好加密证书.......

那么经典问题来了,这也是面试官经常会问到的一个问题:有哪些手段在Spring Boot 项目启动的时候做一些事情?

方法有很多种,下面介绍几种常见的方法。

1、监听容器刷新完成扩展点ApplicationListener<ContextRefreshedEvent>

ApplicationContext事件机制是观察者设计模式实现的,通过ApplicationEvent和ApplicationListener这两个接口实现ApplicationContext的事件机制。

Spring中一些内置的事件如下:

  1. ContextRefreshedEvent:ApplicationContext 被初始化或刷新时,该事件被发布。这也可以在 ConfigurableApplicationContext接口中使用 refresh() 方法来发生。此处的初始化是指:所有的Bean被成功装载,后处理Bean被检测并激活,所有Singleton Bean 被预实例化,ApplicationContext容器已就绪可用。

  2. ContextStartedEvent:当使用 ConfigurableApplicationContext (ApplicationContext子接口)接口中的 start() 方法启动 ApplicationContext 时,该事件被发布。你可以调查你的数据库,或者你可以在接受到这个事件后重启任何停止的应用程序。

  3. ContextStoppedEvent:当使用 ConfigurableApplicationContext 接口中的 stop() 停止 ApplicationContext 时,发布这个事件。你可以在接受到这个事件后做必要的清理的工作。

  4. ContextClosedEvent:当使用 ConfigurableApplicationContext 接口中的 close() 方法关闭 ApplicationContext 时,该事件被发布。一个已关闭的上下文到达生命周期末端;它不能被刷新或重启。

  5. RequestHandledEvent:这是一个 web-specific 事件,告诉所有 bean HTTP 请求已经被服务。只能应用于使用DispatcherServlet的Web应用。在使用Spring作为前端的MVC控制器时,当Spring处理用户请求结束后,系统会自动触发该事件。

好了,了解上面这些内置事件后,我们可以监听ContextRefreshedEvent在Spring Boot 启动时完成一些操作,代码如下:

@Component
public class TestApplicationListener implements ApplicationListener<ContextRefreshedEvent>{@Overridepublic void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {System.out.println(contextRefreshedEvent);System.out.println("TestApplicationListener............................");}
}

高级玩法

可以自定事件完成一些特定的需求,比如:邮件发送成功之后,做一些业务处理。

  1. 自定义EmailEvent,代码如下:

public class EmailEvent extends ApplicationEvent{private String address;private String text;public EmailEvent(Object source, String address, String text){super(source);this.address = address;this.text = text;}public EmailEvent(Object source) {super(source);}//......address和text的setter、getter
}
  1. 自定义监听器,代码如下:

public class EmailNotifier implements ApplicationListener{public void onApplicationEvent(ApplicationEvent event) {if (event instanceof EmailEvent) {EmailEvent emailEvent = (EmailEvent)event;System.out.println("邮件地址:" + emailEvent.getAddress());System.our.println("邮件内容:" + emailEvent.getText());} else {System.our.println("容器本身事件:" + event);}}
}
  1. 发送邮件后,触发事件,代码如下:

public class SpringTest {public static void main(String args[]){ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");//创建一个ApplicationEvent对象EmailEvent event = new EmailEvent("hello","abc@163.com","This is a test");//主动触发该事件context.publishEvent(event);}
}

2、SpringBootCommandLineRunner接口

当容器初始化完成之后会调用CommandLineRunner中的run()方法,同样能够达到容器启动之后完成一些事情。这种方式和ApplicationListener相比更加灵活,如下:

  • 不同的CommandLineRunner实现可以通过@Order()指定执行顺序

  • 可以接收从控制台输入的参数。

下面自定义一个实现类,代码如下:

@Component
@Slf4j
public class CustomCommandLineRunner implements CommandLineRunner {/*** @param args 接收控制台传入的参数*/@Overridepublic void run(String... args) throws Exception {log.debug("从控制台接收参数>>>>"+ Arrays.asList(args));}
}

运行这个jar,命令如下:

java -jar demo.jar aaa bbb ccc

以上命令中传入了三个参数,分别是aaabbbccc,这三个参数将会被run()方法接收到。如下图:

图片

源码分析

读过我的文章的铁粉都应该知道CommandLineRunner是如何执行的,原文:头秃系列,二十三张图带你从源码分析Spring Boot 启动流程~

Spring Boot 加载上下文的入口在org.springframework.context.ConfigurableApplicationContext()这个方法中,如下图:

图片

调用CommandLineRunner在callRunners(context, applicationArguments);这个方法中执行,源码如下图:

图片

3、SpringBootApplicationRunner接口

ApplicationRunnerCommandLineRunner都是Spring Boot 提供的,相对于CommandLineRunner来说对于控制台传入的参数封装更好一些,可以通过键值对来获取指定的参数,比如--version=2.1.0

此时运行这个jar命令如下:

java -jar demo.jar --version=2.1.0 aaa bbb ccc

以上命令传入了四个参数,一个键值对version=2.1.0,另外三个是分别是aaabbbccc

同样可以通过@Order()指定优先级,如下代码:

@Component
@Slf4j
public class CustomApplicationRunner implements ApplicationRunner {@Overridepublic void run(ApplicationArguments args) throws Exception {log.debug("控制台接收的参数:{},{},{}",args.getOptionNames(),args.getNonOptionArgs(),args.getSourceArgs());}
}

通过以上命令运行,结果如下图:

图片

源码分析

CommandLineRunner一样,同样在callRunners()这个方法中执行,源码如下图:

图片

4、@PostConstruct注解

前三种针对的是容器的初始化完成之后做的一些事情,@PostConstruct这个注解是针对Bean的初始化完成之后做一些事情,比如注册一些监听器...

@PostConstruct注解一般放在Bean的方法上,一旦Bean初始化完成之后,将会调用这个方法,代码如下:

@Component
@Slf4j
public class SimpleExampleBean {@PostConstructpublic void init(){log.debug("Bean初始化完成,调用...........");}
}

5、@Bean注解中指定初始化方法

这种方式和@PostConstruct比较类似,同样是指定一个方法在Bean初始化完成之后调用。

新建一个Bean,代码如下:

@Slf4j
public class SimpleExampleBean {public void init(){log.debug("Bean初始化完成,调用...........");}
}

在配置类中通过@Bean实例化这个Bean,不过@Bean中的initMethod这个属性需要指定初始化之后需要执行的方法,如下:

@Bean(initMethod = "init")public SimpleExampleBean simpleExampleBean(){return new SimpleExampleBean();}

6、 InitializingBean接口

InitializingBean的用法基本上与@PostConstruct一致,只不过相应的Bean需要实现afterPropertiesSet方法,代码如下:

@Slf4j
@Component
public class SimpleExampleBean implements InitializingBean {@Overridepublic void afterPropertiesSet()  {log.debug("Bean初始化完成,调用...........");}
}

总结

实现方案有很多,作者只是总结了常用的六种,学会的点个赞。

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

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

相关文章

火爆新品推荐!AI大模型应用和ai 数字人开发!

火爆新品来袭&#xff01;AI大模型应用和AI数字人开发成为当下科技界的热点话题。随着人工智能技术的不断发展&#xff0c;AI大模型应用已经开始在各个领域大放异彩。从医疗诊断到金融风控&#xff0c;从自然语言处理到智能推荐&#xff0c;AI大模型的应用场景愈发广泛&#xf…

PyCharm 显示无法加载文件 D:\...,因为在此系统上禁止运行脚本。

PyCharm 显示无法加载文件 D:…&#xff0c;因为在此系统上禁止运行脚本。 PyCharm 显示 无法加载文件 D:\python test\AI_CV\venv\Scripts\activate.ps1&#xff0c;因为在此系统上禁止运行脚本。 解决方法&#xff1a; winx点击Windows PowerShell&#xff08;管理员&#…

基于yolov5的SAR舰船检测系统,可进行图像目标检测,也可进行视屏和摄像检测(pytorch框架)【python源码+UI界面+功能源码详解】

功能演示&#xff1a; 基于yolov5的SAR舰船检测系统&#xff0c;系统既能够实现图像检测&#xff0c;也可以进行视屏和摄像实时检测_哔哩哔哩_bilibili &#xff08;一&#xff09;简介 基于yolov5的SAR舰船检测系统是在pytorch框架下实现的&#xff0c;这是一个完整的项目&…

爬虫实战——巴黎圣母院新闻【内附超详细教程,你上你也行】

文章目录 发现宝藏一、 目标二、简单分析网页1. 寻找所有新闻2. 分析模块、版面和文章 三、爬取新闻1. 爬取模块2. 爬取版面3. 爬取文章 四、完整代码五、效果展示 发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不…

【python爬虫】免费爬取网易云音乐完整教程(附带源码)

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 所属专栏:爬虫实战,零基础、进阶教学 景天的主页:景天科技苑 文章目录 网易云逆向网易云逆向 https://music.163.com/ 下载云音乐 胡广生等,可以选择自己喜欢的歌曲 首先,我们可以先根据…

使用Pytorch导出自定义ONNX算子

在实际部署模型时有时可能会遇到想用的算子无法导出onnx&#xff0c;但实际部署的框架是支持该算子的。此时可以通过自定义onnx算子的方式导出onnx模型&#xff08;注&#xff1a;自定义onnx算子导出onnx模型后是无法使用onnxruntime推理的&#xff09;。下面给出个具体应用中的…

机器学习中的线性代数

基础知识的的复习: 线性代数——深度学习花书第二章 - 知乎 矩阵分解 特征值分解。 PCA(Principal Component Analysis)分解,作用:降维、压缩。 SVD(Singular Value Decomposition)分解,也叫奇异值分解。 矩阵分解的主要应用是:降维、聚类分析、数据预处理、低维度特征学…

Keepalive 解决nginx 的高可用问题

一 说明 keepalived利用 VRRP Script 技术&#xff0c;可以调用外部的辅助脚本进行资源监控&#xff0c;并根据监控的结果实现优先动态调整&#xff0c;从而实现其它应用的高可用性功能 参考配置文件&#xff1a; /usr/share/doc/keepalived/keepalived.conf.vrrp.localche…

三八妇女节智慧花店/自动售花机远程视频智能监控解决方案

一、项目背景 国家统计局发布的2023年中国经济年报显示&#xff0c;全年社会消费品零售总额471495亿元&#xff0c;比上年增长7.2%。我国无人零售整体发展迅速&#xff0c;2014年市场规模约为17亿元。无人零售自助终端设备市场规模超过500亿元&#xff0c;年均复合增长率超50%。…

正则表达式在QT开发中的应用

一.正则表达式在QT开发中的使用&#xff1a; 1.模式匹配与验证&#xff1a;正则表达式最基本的作用就是进行模式匹配&#xff0c;它可以用来查找、识别或验证一个字符串是否符合某个特定的模式。例如&#xff0c;在表单验证中&#xff0c;可以使用正则表达式来检查用户输入的邮…

Agent——记忆模块

在基于大模型的 Agent架构设计方面,论文[1]提出了一个统一的框架,包括Profile模块、Memory模块、Planning模块和Action模块。其中长期记忆的状态维护至关重要,在 OpenAI AI 应用研究主管 Lilian Weng 的博客《基于大模型的 Agent 构成》[2]中,将记忆视为关键的组件之一,下…

Prompt Engineering、Finetune、RAG:OpenAI LLM 应用最佳实践

一、背景 本文介绍了 2023 年 11 月 OpenAI DevDay 中的一个演讲&#xff0c;演讲者为 John Allard 和 Colin Jarvis。演讲中&#xff0c;作者对 LLM 应用落地过程中遇到的问题和相关改进方案进行了总结。虽然其中用到的都是已知的技术&#xff0c;但是进行了很好的总结和串联…

羊大师分析羊奶滋养,女性魅力绽放

羊大师分析羊奶滋养&#xff0c;女性魅力绽放 羊奶&#xff0c;自古以来便是滋养身心的天然佳品。它富含多种营养成分&#xff0c;如蛋白质、脂肪、矿物质和维生素等&#xff0c;能够为女性提供全面而均衡的营养支持&#xff0c;帮助她们保持健康与活力。 女性是社会的半边天&…

单片机入门:LED数码管

LED数码管 LED数码管&#xff1a;由多个发光二极管封装在一起组成的“8”字型的器件。如下图所示&#xff1a; 数码管引脚定义 一位数码管 内部由八个LED组成。器件有十个引脚。 对于数码管内的8个LED有共阴和共阳两种连接方法。 共阴&#xff1a;将8个LED的阴极都连接到一…

Java项目:41 springboot大学生入学审核系统的设计与实现010

作者主页&#xff1a;源码空间codegym 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 项目介绍 本大学生入学审核系统管理员和学生。 管理员功能有个人中心&#xff0c;学生管理&#xff0c;学籍信息管理&#xff0c;入学办理管理等。 学…

wpf prism左侧抽屉式菜单

1.首先引入包MaterialDesignColors和MaterialDesignThemes 2.主页面布局 左侧菜单显示在窗体外&#xff0c;点击左上角菜单图标通过简单的动画呈现出来 3.左侧窗体外菜单 <Grid x:Name"GridMenu" Width"150" HorizontalAlignment"Left" Ma…

鸿蒙原生应用元服务开发-WebGL网页图形库开发概述

WebGL的全称为Web Graphic Library(网页图形库)&#xff0c;主要用于交互式渲染2D图形和3D图形。目前HarmonyOS中使用的WebGL是基于OpenGL裁剪的OpenGL ES&#xff0c;可以在HTML5的canvas元素对象中使用&#xff0c;无需使用插件&#xff0c;支持跨平台。WebGL程序是由JavaScr…

解读:DUSt3R: Geometric 3D Vision Made Easy

概述&#xff1a;给定一个无约束图像集&#xff0c;即一组具有未知相机姿态和内在特征的照片&#xff0c;我们提出的 DUSt3R 方法会输出一组相应的点阵图&#xff0c;从中我们可以直接恢复通常难以一次性估算的各种几何量&#xff0c;如相机参数、像素对应关系、深度图和完全一…

【PCIe】 PCIe 拓扑结构与分层结构

&#x1f525;博客主页&#xff1a;PannLZ 文章目录 PCIe拓扑结构PCIe分层结构 PCIe拓扑结构 计算机网络中的拓扑结构源于拓扑学(研究与大小、形状无关的点、线关系的方法)。 把网络中的计算机和通信设备抽象为一个点&#xff0c;把传输介质抽象为一条线&#xff0c;由点和线组…

【物联网】stm32芯片结构组成,固件库、启动过程、时钟系统、GPIO、NVIC、DMA、UART以及看门狗电路的全面详解

一、stm32的介绍 1、概述 stm32: ST&#xff1a;指意法半导体 M&#xff1a;指定微处理器 32&#xff1a;表示计算机处理器位数 与ARM关系:采用ARM推出cortex-A&#xff0c;R,M三系中的M系列&#xff0c;其架构主要基于ARMv7-M实现 ARM分成三个系列&#xff1a; Cortex-A&…