Spring中基于事件监听驱动 和 线程池的异步任务
文章目录
- 事件监听驱动 与 异步
- 事件源
- ApplicationContextAware接口
- 发布事件
- 事件实体
- 监听事件
- 实现异步
- 注入綫程池
- 事件驱动机制,与MQ消息队列比较
事件监听驱动 与 异步
事件监听驱动优点:解耦,将 事件和业务进行解耦,通过@Asyc注解可以实现异步
事件监听驱动优点:解耦,将 事件和业务进行解耦,通过@Asyc注解可以实现异步
我们监听事件之前要有事件源source,事件(Event),发布事件(publishEvent),然后才能到监听事件。
事件驱动机制是观察者模式(称发布订阅)具体实现,事件对象(Event)相当于被观察对象(Subject), 事件监听(EventListener) 相当于观察者(Observer)
事件源
实现ApplicationContextAware接口
重写setApplicationContext方法
获取ApplicationContext对象
public class FilePhysicalDeleteEventListener implements ApplicationContextAware {private ApplicationContext applicationContext;@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {this.applicationContext = applicationContext;}
}
ApplicationContextAware接口
ApplicationContext作用具体参考 https://blog.csdn.net/Pluto372/article/details/130139628
在Spring/SpringMVC中,我们拿到IOC容器无非有三种方式,那就是使用ApplicationContext接口下的三个实现类:ClassPathXmlApplicationContext、FileSystemXmlApplicationContext、AnnotationConfigApplicationContext。
但是SpringBoot的强大让我们无需再配置xml文件,也因此我们无法通过上述方式拿到ApplicationContext对象,所以当在项目需要用到spring中的bean对象时,一般做法就是实现ApplicationContextAware接口,通过这个接口就可以获取到ApplicationContext对象,进入从ApplicationContext中获取所需要bean对象。
总结:通过ApplicationContextAware接口获取ApplicationContext对象,ApplicationContext可以获取IOC容器中的bean
发布事件
通过ApplicationContext对象发布
private void physicalDeleteFileByStorageEngine(List<RPanFile> realFileRecords) {//映射为路径集合List<String> realFilePathList = realFileRecords.stream().map(RPanFile::getRealPath).collect(Collectors.toList());DeleteFileContext context = new DeleteFileContext();context.setRealFilePathList(realFilePathList);try {storageEngine.delete(context);} catch (IOException e) {//记录错误日志applicationContext.publishEvent(new ErrorLogEvent(this, "实体文件:" + JSON.toJSONString(realFilePathList) + ", 物理删除失败,请执行手动删除", RPanConstants.ZERO_LONG));}}
事件实体
事件实体需要继承ApplicationEvent对象
@Getter
@Setter
@EqualsAndHashCode
@ToString
public class ErrorLogEvent extends ApplicationEvent {/*** 错误日志的内容*/private String errorMsg;/*** 当前登录的用户ID*/private Long userId;public ErrorLogEvent(Object source, String errorMsg, Long userId) {super(source);this.errorMsg = errorMsg;this.userId = userId;}
}
监听事件
注解@EventListener(ErrorLogEvent.class)方式监听事件
@Component
public class ErrorLogEventListener {@Autowiredprivate IErrorLogService iErrorLogService;/*** 监听系统错误日志事件,并保存到数据库中** @param event*/@EventListener(ErrorLogEvent.class) //监听这个事件@Async(value = "eventListenerTaskExecutor")public void saveErrorLog(ErrorLogEvent event){RPanErrorLog record = new RPanErrorLog();//保存到数据库,调用mp 方法iErrorLogService.save(record);}
}
实现异步
实现异步,并指定线程池任务执行器,value 为指定线程池执行器的 bean的名称。
@Async(value = “eventListenerTaskExecutor”)
当 ErrorLogEvent 事件发生时,相关的处理方法将会以异步的方式执行,
并且将使用指定的任务执行器 “eventListenerTaskExecutor”。不阻塞主线程,提高响应。
public class ErrorLogEventListener {@Autowiredprivate IErrorLogService iErrorLogService;/*** 监听系统错误日志事件,并保存到数据库中** @param event*/@EventListener(ErrorLogEvent.class) //监听这个事件@Async(value = "eventListenerTaskExecutor")public void saveErrorLog(ErrorLogEvent event){RPanErrorLog record = new RPanErrorLog();//保存到数据库,调用mp 方法iErrorLogService.save(record);}
}
注入綫程池
通过Configuration注解和Bean注解以配置类的方式注入线程池
,通过name属性指定bean的名称
@SpringBootConfiguration
public class TreadPoolConfig {// 注入bean// 任务线程池执行器@Bean(name = "eventListenerTaskExecutor")public ThreadPoolTaskExecutor eventListenerTaskExecutor(){ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
// new FutureTask<>();taskExecutor.setCorePoolSize(10);taskExecutor.setMaxPoolSize(10);taskExecutor.setKeepAliveSeconds(200);taskExecutor.setQueueCapacity(2048);taskExecutor.setThreadNamePrefix("event-listener-thread");//拒绝策略// CallerRunsPolicy 既不抛弃任务也不抛出异常,直接使用主线程来执行此任务// abort 直接拒绝并抛异常// discard 丢弃不抛出异常// discardEldest 抛弃队列中等待最久的taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());return taskExecutor;}
}
事件驱动机制,与MQ消息队列比较
MQ驱动的作用:解耦、异步、削峰
优点:解耦,异步,削峰,消息不丢失,解决高并发消息
缺点:难维护
事件驱动机制:解耦、异步,做不到削峰。
优点:维护简单
缺点:大并发扛不住,适合单机环境,消息可能丢失,无法削峰
总结MQ的优点
- 异步解耦
- 应对高并发的消息
- 适用于分布式环境
- 消息不丢失
- 对消息进行 削峰
总结MQ的缺点:
- 分布式场景下引发的复杂问题,如分布式事务等。
相关文章:
Spring中基于事件监听驱动 和 线程池的异步任务
文章目录 事件监听驱动 与 异步事件源ApplicationContextAware接口 发布事件事件实体监听事件实现异步注入綫程池 事件驱动机制,与MQ消息队列比较 事件监听驱动 与 异步 事件监听驱动优点:解耦,将 事件和业务进行解耦,通过Asyc注解…...
C++ 优先级队列用法详解与模拟实现
文章目录 C 优先级队列用法与模拟实现介绍用法头文件1.创建优先级队列priority_queue 2. 插入元素push 3. 删除元素pop 访问顶部元素top 检查优先级队列的大小size 检查优先级队列是否为空empty 模拟实现 C 优先级队列用法与模拟实现 介绍 优先级队列(Priority Qu…...
Linux进阶之旅:深入探索Linux的高级功能
文章目录 Linux进阶之旅:深入探索Linux的高级功能1. Shell脚本编程2. 进程管理3. 网络管理4. 文本处理5. 系统监控6. 总结 Linux进阶之旅:深入探索Linux的高级功能 在上一篇博客中,我们对Linux操作系统进行了入门级的介绍,包括Linux的特点、发行版、安装方法以及基本使用。接下…...
【Java】内存可见性问题是什么?
文章目录 内存模型内存可见性解决方案volatile 内存模型 什么是JAVA 内存模型? Java Memory Model (JAVA 内存模型)是描述线程之间如何通过内存(memory)来进行交互。 具体说来, JVM中存在一个主存区(Main Memory或Java Heap Mem…...
Guava里一些比较常用的工具
随着java版本的更新提供了越来越多的语法和工具来简化日常开发,但是我们一般用的比较早的版本所以体验不到。这时就用到了guava这个包。guava提供了很多方便的工具方法,solar框架就依赖了guava的16.0.1版本,这里稍微介绍下。 一、集合工具类…...
在windows系统中【.gz.tar】和【.whl】文件分别应该怎么下载到conda的某个虚拟环境中
在 Windows 系统中,你可以按照以下步骤将 .gz.tar 和 .whl 文件下载到 Conda 的某个虚拟环境中: 激活虚拟环境:打开 Anaconda Prompt 或者命令行窗口,使用以下命令激活你想要安装文件的虚拟环境: conda activate <虚…...
Rust - 数据类型
Rust 是静态编译语言,在编译时必须知道所有变量的类型。 基于使用的值,编译器通常能推断出它的具体类型,但如果可能的类型比较多,例如把String转换为整数的parse方法,就必须添加类型的标注,否则编译会报错…...
基于springboot实现洗衣店订单管理系统项目【项目源码+论文说明】计算机毕业设计
基于springboot实现洗衣店订单管理系统演示 摘要 随着信息互联网信息的飞速发展,无纸化作业变成了一种趋势,针对这个问题开发一个专门适应洗衣店业务新的交流形式的网站。本文介绍了洗衣店订单管理系统的开发全过程。通过分析企业对于洗衣店订单管理系统…...
Java基础知识总结(53)
(1)集合框架概述 Java集合大致分为List、Set、Map和Queue Collection是一个顶级接口,其子接口有,List、Set、Queue List:有序(存放和取出顺序是一致的)、有索引、可重复 Set:无序、无索引、不可重复 &…...
196算法之谜在 JSP 中使用内置对象 request 获取 form 表单的文本框 text 提交的数据。
(1)编写 inputNumber . jsp ,该页面提供一个 form 表单,该 form 表单提供一个文本框 text ,用于用户输入一个正整数,用户在 form 表单中输入的数字,单击 submit 提交键将正整数提交给 huiwenNumber . jsp 页…...
初识责任链模式--一起学习吧之数据库
一、定义 责任链模式是一种对象行为型模式,用于处理请求发送者和多个请求处理者之间的耦合问题。在这种模式中,请求的处理者通过前一对象记住其下一个对象的引用而连成一条链。当有请求发生时,请求会沿着这条链传递,直到有对象处…...
解决Xshell登录云服务器的免密码和云服务器生成子用户问题
Xshell登录云服务器的免密码问题 前言一、Xshell登录云服务器的免密码操作实践 二、centos创建用户创建用户实操删除用户更改用户密码直接删除子用户 前言 Xshell登录云服务器免密码问题的解决方案通常涉及使用SSH密钥对。用户生成一对密钥(公钥和私钥)…...
webRtc生产环境实用方法
最近做了几个项目发现多个项目反反复复会出现几个高频的需求, 都依赖于获取系统采集设备和指定设备id获取媒体流;为了不在反复书写总结2个公用方法; 检索当前系统所有可用设备 /*** 检索当前系统所有可用设备* returns {* audioInputOption…...
Java String、StringBuffer
构造方法 通过字符数组构造,结果abc 通过字节数组构造,结果abc //把字符串转化为字节数组 当前代码编译环境为UTF-8,出现异常时,直接抛出异常即可。mainthrows UnsupportedEncodingException 编译环境为UTF-8,但是运用gb2312这个…...
LangChain调用tool集的原理剖析(包懂)
一、需求背景 在聊天场景中,针对用户的问题我们希望把问题逐一分解,每一步用一个工具得到分步答案,然后根据这个中间答案继续思考,再使用下一个工具得到另一个分步答案,直到最终得到想要的结果。 这个场景非常匹配la…...
如何正确使用数字化仪前端信号调理?(一)
一、前言 板卡式的数字转换器和类似测量仪器,比如图1所示的德思特TS-M4i系列,都需要为各种各样的特性信号与内部模数转换器(ADC)的固定输入范围做匹配。 图1:德思特TS-M4i系列高速数字化仪,包括2或4通道版…...
实验5 流程图和盒图ns图
一、实验目的 通过绘制流程图和盒图,熟练掌握流程图和盒图的基本原理。 能对简单问题进行流程图和盒图的分析,独立地完成流程图和盒图设计。 二、实验项目内容(实验题目) 1、用Microsoft Visio绘制下列程序的程序流程图。 若…...
[Java、Android面试]_18_详解Handler机制 常见handler面试题(非常重要,非常高频!!)
本人今年参加了很多面试,也有幸拿到了一些大厂的offer,整理了众多面试资料,后续还会分享众多面试资料。 整理成了面试系列,由于时间有限,每天整理一点,后续会陆续分享出来,感兴趣的朋友可关注收…...
国内开通gpt会员方法
ChatGPT镜像 今天在知乎看到一个问题:“平民不参与内测的话没有账号还有机会使用ChatGPT吗?” 从去年GPT大火到现在,关于GPT的消息铺天盖地,真要有心想要去用,途径很多,别的不说,国内GPT的镜像…...
使用 Meltano 将数据从 Snowflake 导入到 Elasticsearch:开发者之旅
作者:来自 Elastic Dmitrii Burlutskii 在 Elastic 的搜索团队中,我们一直在探索不同的 ETL 工具以及如何利用它们将数据传输到 Elasticsearch,并在传输的数据上实现 AI 助力搜索。今天,我想与大家分享我们与 Meltano 生态系统以及…...
多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验
一、多模态商品数据接口的技术架构 (一)多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如,当用户上传一张“蓝色连衣裙”的图片时,接口可自动提取图像中的颜色(RGB值&…...
论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)
笔记整理:刘治强,浙江大学硕士生,研究方向为知识图谱表示学习,大语言模型 论文链接:http://arxiv.org/abs/2407.16127 发表会议:ISWC 2024 1. 动机 传统的知识图谱补全(KGC)模型通过…...
智能仓储的未来:自动化、AI与数据分析如何重塑物流中心
当仓库学会“思考”,物流的终极形态正在诞生 想象这样的场景: 凌晨3点,某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径;AI视觉系统在0.1秒内扫描包裹信息;数字孪生平台正模拟次日峰值流量压力…...
Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理
引言 Bitmap(位图)是Android应用内存占用的“头号杀手”。一张1080P(1920x1080)的图片以ARGB_8888格式加载时,内存占用高达8MB(192010804字节)。据统计,超过60%的应用OOM崩溃与Bitm…...
pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)
目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关࿰…...
在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?
uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件,用于在原生应用中加载 HTML 页面: 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...
08. C#入门系列【类的基本概念】:开启编程世界的奇妙冒险
C#入门系列【类的基本概念】:开启编程世界的奇妙冒险 嘿,各位编程小白探险家!欢迎来到 C# 的奇幻大陆!今天咱们要深入探索这片大陆上至关重要的 “建筑”—— 类!别害怕,跟着我,保准让你轻松搞…...
uniapp 字符包含的相关方法
在uniapp中,如果你想检查一个字符串是否包含另一个子字符串,你可以使用JavaScript中的includes()方法或者indexOf()方法。这两种方法都可以达到目的,但它们在处理方式和返回值上有所不同。 使用includes()方法 includes()方法用于判断一个字…...
[ACTF2020 新生赛]Include 1(php://filter伪协议)
题目 做法 启动靶机,点进去 点进去 查看URL,有 ?fileflag.php说明存在文件包含,原理是php://filter 协议 当它与包含函数结合时,php://filter流会被当作php文件执行。 用php://filter加编码,能让PHP把文件内容…...
解析奥地利 XARION激光超声检测系统:无膜光学麦克风 + 无耦合剂的技术协同优势及多元应用
在工业制造领域,无损检测(NDT)的精度与效率直接影响产品质量与生产安全。奥地利 XARION开发的激光超声精密检测系统,以非接触式光学麦克风技术为核心,打破传统检测瓶颈,为半导体、航空航天、汽车制造等行业提供了高灵敏…...
