使用spring自带的发布订阅来实现发布订阅

news2024/11/19 10:27:01

背景

公司的项目以前代码里面有存在使用spring自带发布订阅的代码,因此稍微学习一下如何使用,并了解一下这种实现方式的优缺点。

优点

  • 实现方便,代码方面基本只需要定义消息体和消费者,适用于小型应用程序。
  • 不依赖外部中间件,因而不需要复杂的配置、部署。

缺点

  • 无法提供消息持久性,项目一旦重启,消息就会丢失,因而不适合实现延迟队列。
  • 对比消息队列,无法实现复杂的消息过滤、路由过滤。
  • 无法实现跨应用程序的事件通信。不同应用程序之间的事件发布和订阅更为容易。

发布订阅模式的优缺点我就不说了,就说说不同实现方式之间的优缺点。

一、创建消息类

消息类需要继承ApplicationEvent类。因为java调用构造函数的机制就是默认会调用父类的构造函数,而ApplicationEvent类只有一个单参数的构造函数,无法自动调用,每个构造函数都需要显式调用父类的构造函数。也就是super(source);

package org.jeecg.modules.test.testPublic;
import org.springframework.context.ApplicationEvent;
import java.util.Objects;

/**
 * @ClassName: MyEvent
 * @Author: zjc
 * @Date: 2023/8/30 18:22
 * @Description:
 **/
public class MyEvent extends ApplicationEvent {
	private String taskId;
	private Integer sourceType;
	
	public MyEvent(Object source) {
		super(source);
	}
	/**
	 *
	 *  @param source   触发事件的对象,可随便传,不过建议传自己可能用得到的对象。好像在调用放直接this的挺多
	 * @param taskId    任务id,自己定义的事件要处理的内容
	 * @param sourceType    自己定义的源类型,用来在多场景触发情况下区分不同场景的标志
	 * @return: null
	 **/
	public MyEvent(Object source,String taskId,Integer sourceType) {
		super(source);
		this.taskId=taskId;
		this.sourceType=sourceType;
	}

	public String getTaskId() {
		return taskId;
	}

	public void setTaskId(String taskId) {
		this.taskId = taskId;
	}

	public Integer getSourceType() {
		return sourceType;
	}

	public void setSourceType(Integer sourceType) {
		this.sourceType = sourceType;
	}

	@Override
	public boolean equals(Object o) {
		if (this == o) return true;
		if (o == null || getClass() != o.getClass()) return false;
		MyEvent myEvent = (MyEvent) o;
		return Objects.equals(taskId, myEvent.taskId) && Objects.equals(sourceType, myEvent.sourceType);
	}

	@Override
	public int hashCode() {
		return Objects.hash(taskId, sourceType);
	}

	@Override
	public String toString() {
		return "MyEvent{" +
				"taskId='" + taskId + '\'' +
				", sourceType=" + sourceType +
				'}';
	}
}

二、发布消息

发布消息可以直接使用ApplicationContext对象调用publishEvent方法。因为ApplicationContext接口继承了ApplicationEventPublisher接口。注意消息类必须要继承ApplicationEvent类才能作为参数发布消息。

package org.jeecg.modules.test.testPublic;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @ClassName: EventController
 * @Author: 
 * @Date: 2023/8/31 17:53
 * @Description:
 **/
@RestController
@Api("test")
@RequestMapping("/test")
public class EventController {
	@Autowired
	private ApplicationContext applicationContext;
	@ApiOperation("testEvent")
	@GetMapping("/testEvent")
	public void testEvent(){
		MyEvent myEvent=new MyEvent(this,"123456",1);
		applicationContext.publishEvent(myEvent);
	}
	@ApiOperation("testEvent1")
	@GetMapping("/testEvent1")
	public void testEvent1(){
		MyEvent myEvent=new MyEvent(this,"123456",2);
		applicationContext.publishEvent(myEvent);
	}
}

三、监听消息

监听消息类需要实现ApplicationListener接口,并通过泛型传入要监听的消息类,并重写onApplicationEvent方法。spring内的同一个消息可以有多个监听类,一旦监听到消息,监听该消息的全部监听类都会执行。

监听类1:

package org.jeecg.modules.test.testPublic;

import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

/**
 * @ClassName: MyEventListener
 * @Author: 
 * @Date: 2023/8/31 17:50
 * @Description:
 **/
@Component
public class MyEventListener implements ApplicationListener<MyEvent> {
	@Override
	public void onApplicationEvent(MyEvent event) {
		System.out.println("消费者开始消费"+event.toString()+event.getSource().toString());
	}
}

消费者2

package org.jeecg.modules.test.testPublic;

import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

/**
 * @ClassName: MyEventListener
 * @Author: 
 * @Date: 2023/8/31 17:50
 * @Description:
 **/
@Component
public class MyEventListener1 implements ApplicationListener<MyEvent> {
	@Override
	public void onApplicationEvent(MyEvent event) {
		System.out.println("消费者1开始消费"+event.toString()+event.getSource().toString());
	}
}

四、测试

调用testEvent接口

在这里插入图片描述

调用testEvent1接口

在这里插入图片描述

结果均符合预期,可以通过在消息体里面加一个字段来区分消息来着不同的触发场景。
即使没有在结构体加上区分消息来源的标识,也可以用消息一开始传入的源对象来大概定位到是哪一个类里面触发的消息。

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

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

相关文章

学习高级数据结构:探索平衡树与图的高级算法

文章目录 1. 平衡树&#xff1a;维护数据的平衡与高效性1.1 AVL 树&#xff1a;严格的平衡1.2 红黑树&#xff1a;近似平衡 2. 图的高级算法&#xff1a;建模复杂关系与优化2.1 最小生成树&#xff1a;寻找最优连接方式2.2 拓扑排序&#xff1a;解决依赖关系 拓展思考 &#x1…

el-select下拉多选框 el-select 设置默认值不可删除功能

Element3.0vue3.0 el-select下拉多选框 el-select 设置默认值不可删除功能 Element-UI是一款广泛使用的Vue.js组件库&#xff0c;其中El-Select下拉多选框组件在实际项目开发中经常被使用。然而&#xff0c;在Element 3.0版本中&#xff0c;El-Select下拉多选框默认值可被删除&…

降本56%!纵腾集团搭载OceanBase Cloud开启降本增效新篇章

近日&#xff0c;跨境电商物流领跑企业福建纵腾网络有限公司&#xff08;以下简称“纵腾集团”&#xff09;正式商用原生分布式数据库 OceanBase&#xff0c;为其下专业物流服务“云途物流”提供云数据库支撑服务。目前&#xff0c;已有两大关键业务系统全部接入 OceanBase Clo…

基于JAVAEE技术的ssm校园车辆管理系统源码和论文

基于JAVAEE技术的ssm校园车辆管理系统源码和论文105 开发工具&#xff1a;idea 数据库mysql5.7 数据库链接工具&#xff1a;navcat,小海豚等 技术&#xff1a;ssm 1.选题背景和意义 背景&#xff1a; 随着第二次工业革命后&#xff0c;内燃机的发明与完善&#xff0c;解…

Charles信任证书后依然无法抓包的解决方案

前提 1、Charles安装证书 2、Charles设置SSL代理 3、查看Android安装Charles证书的方法 4、查看Android安装的Charles证书 问题 Charles拦截时&#xff0c;报“SSL handshake with client failed: An unknown issue occurred processing the certificate (certificate_unknow…

Ubuntu20.04安装ROS

Ubuntu20.04安装ROS Excerpt ubuntu安装方式有两种&#xff0c;一种是安装ubuntu系统&#xff0c;另一种是在windows下安装虚拟机&#xff0c;在虚拟机里安装ubuntu。下面为双系统安装ubuntu&#xff08;用虚拟机装ubuntu会很卡&#xff0c;bug很多&#xff0c;除非电脑配置极好…

UI按钮设计原则,让你的产品一次打动用户!

UI按钮是常见的界面组件,广泛应用于表单、对话框以及工具栏等场景。与链接不同,按钮用于让用户执行特定操作,如提交、删除等;而链接则将用户引导到新的页面。优秀的按钮设计能极大地提高用户的操作效率和转化率。本文将全面介绍按钮设计的相关指南,并通过实例解析如何设计出能最…

Android之布局转圆角

Android之布局转圆角 文章目录 Android之布局转圆角说明一、效果图二、实现步骤1.自定义RoundRelativeLayout2.使用 总结 说明 很多需求比较无语&#xff0c;需要某个布局转圆角&#xff0c;像个显眼包一样&#xff0c;所以为了满足显眼包&#xff0c;必须整呐提示&#xff1a…

01_lwip_raw_udp_test

1.打开UDP的调试功能 &#xff08;1&#xff09;设置宏定义 &#xff08;2&#xff09;打开UDP的调试功能 &#xff08;3&#xff09;修改内容&#xff0c;串口助手打印的日志信息自动换行 2.电脑端连接 UDP发送一帧数据 3.电路板上发送一帧数据

k8s etcd 简介

Etcd是CoreOS基于Raft协议开发的分布式key-value存储&#xff0c;可用于服务发现、共享配置以及一致性保障&#xff08;如数据库选主、分布式锁等&#xff09;。 如&#xff0c;Etcd也可以作为微服务的注册中心&#xff0c;比如SpringCloud也基于ETCD实现了注册中心功能&#…

如何利用Python代码优雅的进行文件下载

如何利用Python代码优雅的进行文件下载 一、什么是wget&#xff1f;二、使用wget.exe客户端进行文件下载三、使用Python脚本进行文件下载 欢迎学习交流&#xff01; 邮箱&#xff1a; z…1…6.com 网站&#xff1a; https://zephyrhours.github.io/ 一、什么是wget&#xff1f;…

【LeetCode算法系列题解】第6~10题

CONTENTS LeetCode 6. N 字形变换&#xff08;中等&#xff09;LeetCode 7. 整数反转&#xff08;中等&#xff09;LeetCode 8. 字符串转换整数-atoi&#xff08;中等&#xff09;LeetCode 9. 回文数&#xff08;简单&#xff09;LeetCode 10. 正则表达式匹配&#xff08;困难&…

hadoop的hadoop.tmp.dir安装时一定要更改

hadoop的hadoop.tmp.dir安装时一定要更改 hadoop.tmp.dir 属性确保了 HDFS 元数据的存储位置&#xff0c;其中包含了一些关键的文件&#xff0c;如&#xff1a; fsimage 文件&#xff1a;这是 HDFS 的文件系统镜像&#xff0c;记录了整个文件系统命名空间的状态。它包含所有文…

飞腾PSPA可信启动--4 可信固件环境搭建和打包

今天继续第四章&#xff0c;飞腾可信固件环境搭建和打包介绍。 此章节录制了讲解视频&#xff0c;可以在B站进行观看&#xff1a; Gmssl-master文件&#xff0c;可以关注公众号“乌拉大喵喵”后回复“Gmssl”获取。&#xff08;区分大小写&#xff09;

方案小知识

云平台 云平台也称云计算平台. 云计算, 顾名思义, 就是将计算在云上运行. 那么在这里面的3个概念 云: 通俗的理解就是远程计算机, 并且是一组 一堆, 这些远程计算机协同工作构建出一个平台&#xff0c;对用户提供服务计算&#xff1a;这是一个概念很大的名词&#xff0c;小了…

Nacos服务发起注册找不到nacos

错误概述 service启动报错&#xff0c;显示服务发起注册的时候找不到nacos failed to req API:/nacos/v1/ns/instance after all servers([localhost:8845]) tried: ErrCode:400, ErrMsg:<html><body><h1>Whitelabel Error Page</h1><p>This …

SOD-123FL贴片整流二极管,有哪些型号?

近日发现&#xff0c;客户对整流二极管的需求特别大。常有客户前来东沃电子咨询整流二极管型号参数、选型、替代、价格、交期、样品等方面的问题。那么&#xff0c;关于DS1A、DS1B、DS1D、DS1G、DS1J、DS1K、DS1M贴片整流二极管&#xff0c;您知道多少呢&#xff1f;东沃电子推…

免费试用,畅享海量内容!快来体验Netflix首月福利

Netflix是一家全球知名的流媒体服务平台,通过提供海量的电影、电视剧、纪录片和动画等各种类型的内容,迅速赢得了全球观众的喜爱。作为一项以订阅制为基础的在线视频服务,Netflix为用户提供了无限制的观影体验,让用户可以根据自己的兴趣和喜好随时随地畅享精彩的影视内容。 Ne…

新一代AI换脸和人脸增强软件及使用教程!facefusion

又有新东西咯&#xff01; roop停更了&#xff0c;核心开发者独立发布了一个项目&#xff0c;就是这个叫facefusion的项目。官方介绍为下一代的人脸交换和增强软件。 这是官方预览图&#xff0c;又红又紫&#xff0c;确实有点fusion的感觉。 这次的软件使用gradio构建了WebUI&…