【Spring】ApplicationEventPublisher 发布订阅模式

概念

        关于发布订阅这个词,其实不仅仅出现在Spring框架当中,其实在Redis中也有存在(其对应的是convertAndSend()方法),还有在MQ消息队列里也是有的,但这里就主要介绍的是关于Spring框架的ApplicationEventPublisher如何做到消息的发布与订阅。随着现在的业务量和需求量越来越大,其实基本都是分布式微服务集群的使用了,所以基本都是用到Redis与MQ。但是对于单体Spring Boot应用时,用Spring自带的发布订阅就已经绰绰有余了。

        需要知道的是发布订阅需要有三个对象:事件事件发布源事件接收源(监听器)

事件

        对于事件来说,需要去继承ApplicationEvent。至于为什么需要继承ApplicationEvent就需要研究源码,等我后续看完再回来更新笔记。

public class LogEvent extends ApplicationEvent {

    public LogEvent(Object message) {
        super(message);
    }
}

事件发布源

        这个基本上都是业务层的代码,但是作为学习阶段,我将其直接放在控制层。关于如何去发布,就需要用到Spring中的ApplicationEventPublisher。

@Slf4j
@RestController
@RequestMapping("/log")
public class LogController {

    @Autowired
    private ApplicationEventPublisher publisher;

    @GetMapping("/publisher")
    public void log() {
        log.info("进入到log方法,开始发送事件");
        publisher.publishEvent(new LogEvent("log方法生成事件信息"));
        log.info("log方法发送事件完毕");
    }

}

监听器

/**
 * 管理员日志监听器
 */
@Slf4j
@Component
public class AdminListener {

    @EventListener(LogEvent.class)
    public void adminListen(LogEvent logEvent) {
        try {
            log.info("管理员监听到的日志信息为,{}", logEvent);
            Thread.sleep(5000); // 睡眠5s
            log.info("管理员监听完毕");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
/**
 * 用户日志事件监听器
 */
@Slf4j
@Component
public class UserListener {

    @EventListener(LogEvent.class)
    public void userListen(LogEvent logEvent) {
        try {
            log.info("用户监听到的日志信息为,{}", logEvent);
            Thread.sleep(10000); // 睡眠10s
            log.info("用户监听完毕");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

执行结果

        从执行结果可以发现管理员线程睡眠了5s后执行完毕才会执行用户的代码块。所以表明是同步执行的。

        于是为了将同步执行变为异步执行,又在两个监听器的方法上添加了@Async注解,并且一定要在启动类上添加@EnableAsync注解。再次执行会发现两次的执行结果并不一致。两个监听器是异步执行的。甚至在监听器上放置@Order注解可以实现先后顺序,但这里就不演示了。

源码追踪

        这里只进行粗略的源码查看,因为作者功力有限无法解释得完全仔细,以后看懂了再回来更新笔记。可以发现其已经使用了JDK8新特性了。从ApplicationEventPublisher的publisher(Application event)方法就会进入到其子类AbstartApplicationContext中。

protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
        Assert.notNull(event, "Event must not be null");
        Object applicationEvent;
        if (event instanceof ApplicationEvent) {
            applicationEvent = (ApplicationEvent)event;
        } else {
            applicationEvent = new PayloadApplicationEvent(this, event);
            if (eventType == null) {
                eventType = ((PayloadApplicationEvent)applicationEvent).getResolvableType();
            }
        }

        if (this.earlyApplicationEvents != null) {
            this.earlyApplicationEvents.add(applicationEvent);
        } else {
            // 在这步完成真正的发布订阅 只有监听完才会向下继续执行
            this.getApplicationEventMulticaster().multicastEvent((ApplicationEvent)applicationEvent, eventType);
        }

        if (this.parent != null) {
            if (this.parent instanceof AbstractApplicationContext) {
                ((AbstractApplicationContext)this.parent).publishEvent(event, eventType);
            } else {
                this.parent.publishEvent(event);
            }
        }

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

怎么把PDF转为word?1分钟解决难题

PDF文件在我们的电脑上应用非常广泛,由于其较高的安全性和兼容性,得到了广泛的认可。然而,对于一些人来说,PDF文件不能直接进行编辑和修改可能是一个问题。因此,通常我们需要将其转换为Word格式,以便在Word…

成为“AI+的UGC社交平台”,亚马逊云科技助力博宇盖乐向“3D UGC社交门户”迈进

随着元宇宙浪潮逐渐升温,以玩家为主导的UGC游戏平台获得空前关注。多元化的视觉呈现方式,人人可参与、交互的玩法生态,具有UGC属性的游戏平台在极大提升玩家参与度、增加游戏趣味性的同时,也为游戏行业的内容创作带来了新的想象空…

5分钟开发一个AI论文抓取和ChatGPT提炼应用

5分钟开发一个AI论文抓取和ChatGPT提炼应用 第一步 点击“即刻开始” -选择模板 python -修改标题 “AIPaper”,项目标识“AIPaper”,点击“创建项目” 第二步 在编程区域右侧AI区域,输入框输入以下内容: 请根据下面的内容&…

MacBook外接键盘修改键位

众所周知,MacBook的键盘和Windows差别很大,比如我们最常用的ctrlcv在Mac下是commandcv…而外接键盘往往是Windows布局,因此如何修改外接键盘键位就是一件很重要的事情! 首先,我们要知道Win键在Mac系统中是多余的&…

客户案例 | 思腾合力服务器助力西安电子科技大学人工智能实验室建设

客户介绍 西安电子科技大学是以信息与电子学科为主,工、理、管、文多学科协调发展的全国重点大学,直属教育部,是国家“优势学科创新平台”项目和“211工程”项目重点建设高校之一、国家双创示范基地之一、首批35所示范性软件学院、首批9所示范…

机器学习术语解析与应用(一)

文章目录 🍀引言🍀数据集🍀特征工程(Feature Engineering)🍀模型(Model)🍀算法(Algorithm)🍀训练(Training)&a…

电脑风扇声音大怎么办?最全解决方法分享!

家人们谁懂啊!电脑风扇声音太大了,每天用电脑的时候都感觉特别特别的吵,真的非常窒息,有什么方法可以改善电脑风扇声太吵的情况吗? 电脑风扇是保持电脑内部温度稳定的重要组件,其正常运行有利于保障我们电脑…

学好Elasticsearch系列-核心概念

本文已收录至Github,推荐阅读 👉 Java随想录 文章目录 节点角色master:候选节点data:数据节点Ingest:预处理节点ml:机器学习节点remote_ cluster_ client:候选客户端节点transform:…

Flutter实现点击头像更新头像的功能,本地相册选取和调用相机两种方式的实现

文章目录 需求实现的效果如图代码实现代码分析用InkWell包住了我们的头像,这样来监听点击头像的事件用showDialog弹出提示框让用户选择是从相册里选择头像还是使用相机来拍照用image_picker实现从设备的相册或相机中选择图片或拍照 需求 Flutter实现点击头像更新头…

vite打包性能优化以及填坑

目录 前言 项目优化前 分析 优化 拆分包 去除debugger CDN 加速 按需导入 文件压缩 图片压缩 viteImagemin报错 填坑 坑1 坑2 总结 配置 前言 最近在使用 Vite4.0 构建一个中型前端项目的过程中,遇到了一些坑,也做了一些项目在构建生产环…

【C语言项目】三子棋

文章目录 项目思路一、分文件进行创建二、进入游戏前的目录2.1 目录的功能:2.2 目录界面:2.3 选择进入或退出游戏2.4 多次重玩功能 三、画出棋盘3.1 写出棋子3.2 初始化棋盘3.2 画出棋盘的框架3.3 代码实现 四、玩家落子4.1 落子逻辑4.2具体情况分类讨论…

Java 贪心算法经典问题解决

文章目录 分金条题目思路代码实现测试用例以及结果输出 花费资金做项目最大收益题目思路代码实现测试用例以及结果输出 预定会议室题目思路代码实现测试用例以及结果输出 取中位数题目思路代码实现测试用例以及结果输出 最低字典序题目思路代码实现测试用例以及结果输出 结语 分…

(20)操纵杆或游戏手柄

文章目录 前言 20.1 你将需要什么 20.2 校准 20.3 用任务规划器进行设置 20.4 飞行前测试控制装置 20.5 测试失控保护 20.6 减少控制的滞后性 前言 本文解释了如何用操纵杆或游戏手柄控制你的飞行器,使用任务计划器向飞行器发送"RC Override"消息…

【深入浅出 Yarn 架构与实现】 NodeManager 状态机管理

一、简介# NodeManager(NM)中的状态机分为三类:Application、Container 和 LocalizedResource,它们均直接或者间接参与维护一个应用程序的生命周期。 当 NM 收到某个 Application 的第一个 container 启动命令时,它会…

接口自动化测试-Python+Requests+Pytest+YAML+Allure配套撸码(详细)

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 接口自动化框架&a…

vue2项目迁移到vue3中的改动——基础积累

最近在跟着大神学习vue3的内容,发现之前vue2写的代码可以直接照搬到vue3中,但是有一些需要改动的内容,下面做一下记录。 1.定义对象时,需要指定每个属性值 例如:listQuery:{} 如果使用:listQuery.Filter…

chrome查看浏览器内核日志

由于经常在网页上调试播放音视频,但是总遇到一些未知原因,导致无法正常播放,亟需查看浏览器内核日志,分析原因,做一下笔记。 (1) 查看浏览器快捷键属性 (2)在快捷键启动位置补充参数 --enable-…

LabVIEW可重入VI,VI模板和动态VI之间的差异

LabVIEW可重入VI,VI模板和动态VI之间的差异 应该在何时使用可重入VI、模板VI和动态调用VI?这三种类型之间有什么区别? 可重入VI 当想要同时运行同一VI的多个实例时,将使用可重入VI。当VI不可重入时,VI只有一个数据空…

opencv对相机进行畸变矫正,及从矫正后的图像坐标反求原来的对应坐标

1.背景 目前有个项目,需要用到热成像相机。但是这个热成像相机它的畸变比较厉害,因此需要用标定板进行标定,从而消除镜头畸变。 同时需要实现用户用鼠标点击矫正后的画面后,显示用户点击位置的像素所代表的温度。 2.难点 消除镜…

11 spring-boot的MVC配置原理

11.1 spring-boot为MVC提供的自动配置 1.ContentNegotiatingViewResolver视图解析器; 2.静态资源或者支持WebJars; 3.自动注册类型转换器:比如说前台提交user的字段,后台自动封装的意思; 4.HttpMessageConverters&…