篇章五 项目创建

news2025/7/13 22:44:36

目录

1.创建一个SpringBoot项目

2.创建核心类

2.1 Exchange类

2.2 MessageQueue类

2.3 Binding类

2.4 Message类

1.Message的组成

2.逻辑删除

3.工厂方法

4.序列化与反序列化

5.offsetBeg和offsetEnd

1.创建一个SpringBoot项目

1.点击

2.填写表单

3.添加依赖

2.创建核心类

创建好Spring Boot项目就可以开始创建核心类了

消息队列中核心概念:

1.交换机

2.队列

3.绑定

4.消息

都存在于Broker Server中

2.1 Exchange类

1.关于持久化的理解

// 交换机是否要持久化存储 true 需要持久化; false 不必持久化
private boolean durable = false;

有些交换机,队列,绑定,是需要持久化的,有些则不需要,所以可以设置开关来让用户决定是否需要持久化

2.关于arguments的理解

RabbitMQ中 Exchange的 x-arguments

参考网址https://www.rabbitmq.com/docs/exchanges#ae

2.2 MessageQueue类

所需要的属性及注释

// 队列的身份标识
private String name;

// 队列是否持久化 true 表示持久化保存
private boolean durable = false;

// 队列是否独占 ture 表示这个队列只能被一个消费者使用
// 并未实现该功能(留着扩展)(RabbitMQ实现了)
private boolean exclusive = false;

// 如果当前队列 没人(消费者)使用 就会自动删除
// 并未实现自动删除功能(留着扩展)(RabbitMQ实现了)
private boolean autoDelete = false;

// 创建队列时 指定的一些额外的参数选项
// 并未实现该功能(留着扩展)(RabbitMQ实现了)
private Map<String, Object> arguments = new HashMap<>();

2.3 Binding类

public class Binding {

    private String exchangeName;

    private String queueName;

    // 支持 TOPIC主题交换机 相当于 出题角色
    private String bindingKey;

    public String getExchangeName() {
        return exchangeName;
    }

    public void setExchangeName(String exchangeName) {
        this.exchangeName = exchangeName;
    }

    public String getQueueName() {
        return queueName;
    }

    public void setQueueName(String queueName) {
        this.queueName = queueName;
    }

    public String getBindingKey() {
        return bindingKey;
    }

    public void setBindingKey(String bindingKey) {
        this.bindingKey = bindingKey;
    }
}

为什么Binding没有durable 、autoDelete 这两个属性 ?

因为Exchange或者MessageQueue中有一个没有持久化,单独持久化他们的Binding是没有意义的。

2.4 Message类

public class Message implements Serializable {
    // Massage 最核心的部分
    private BasicProperties basicProperties = new BasicProperties();
    private byte[] body;

    // 以下是: 辅助属性
    // 如果要存储到文件中(持久化)
    // 一个文件会存储很多的消息, 如何找到某个消息, 在文件中的具体位置?
    // 使用下列的 两个偏移量 来进行表示 [offsetBeg, offsetEnd)
    // 这两个属性并不需要序列化保存到文件中
    // 1.此时消息被写入文件后 所在的位置固定 并不需要存储这两个属性
    // 2.属性存在的目的:为了让内存中的Message对象, 能够快速找到对应的硬盘上的Message的位置
    private transient long offsetBeg = 0; // 消息数据的开头距离文件开头的位置偏移(字节)
    private transient long offsetEnd = 0; // 消息数据的结尾距离文件开头的位置便宜(字节)

    // 使用这个属性表示该消息在文件中是否是有效消息(逻辑删除)
    // 0x1 表示有效  0x0 表示无效
    private byte isValid = 0x1;

    // 创建一个工厂方法 封装 创建Message对象的而过程
    // 此方法 创建的Message对象 会 自动生成 唯一的MessageId
    // 如果 routingKey 和 basicProperties 中的 routingKey 冲突了 以外面为主
    public static Message createMessageWithId(String routingKey, BasicProperties basicProperties, byte[] body){
        Message message = new Message();
        if (basicProperties != null) {
            message.setBasicProperties(basicProperties);
        }
        // 此处加上 "M-" 前缀 区分不同实体的ID
        message.setMessageId("M-" + UUID.randomUUID());
        message.basicProperties.setRoutingKey(routingKey);
        message.body = body;
        return message;
    }

    public String getMessageId() {
        return basicProperties.getMessageId();
    }

    public void setMessageId(String messageId) {
        basicProperties.setMessageId(messageId);
    }

    public String getRoutingKey() {
        return basicProperties.getRoutingKey();
    }

    public void setRoutingKey(String routingKey) {
        basicProperties.setRoutingKey(routingKey);
    }

    public int getDeliverMode() {
        return basicProperties.getDeliverMode();
    }

    public void setDeliverMode(int mode) {
        basicProperties.setDeliverMode(mode);
    }

    public BasicProperties getBasicProperties() {
        return basicProperties;
    }

    public void setBasicProperties(BasicProperties basicProperties) {
        this.basicProperties = basicProperties;
    }

    public byte[] getBody() {
        return body;
    }

    public void setBody(byte[] body) {
        this.body = body;
    }

    public long getOffsetBeg() {
        return offsetBeg;
    }

    public void setOffsetBeg(long offsetBeg) {
        this.offsetBeg = offsetBeg;
    }

    public long getOffsetEnd() {
        return offsetEnd;
    }

    public void setOffsetEnd(long offsetEnd) {
        this.offsetEnd = offsetEnd;
    }

    public byte getIsValid() {
        return isValid;
    }

    public void setIsValid(byte isValid) {
        this.isValid = isValid;
    }


}

1.Message的组成

1.属性部分 BasicProperties

2.正文部分 byte[]

为什么正文部分不用 String[]?

因为String[] 只能存储文本,所以采用byte[] 增加 通用性

2.逻辑删除

字段解析:private byte isValid = 0x1;

与数据库相同,删除数据使用逻辑删除。不是真正的删除而是标记为无效。

3.工厂方法

// 创建一个工厂方法 封装 创建Message对象的而过程
    // 此方法 创建的Message对象 会 自动生成 唯一的MessageId
    // 如果 routingKey 和 basicProperties 中的 routingKey 冲突了 以外面为主
    public static Message createMessageWithId(String routingKey, BasicProperties basicProperties, byte[] body){
        Message message = new Message();
        if (basicProperties != null) {
            message.setBasicProperties(basicProperties);
        }
        // 此处加上 "M-" 前缀 区分不同实体的ID
        message.setMessageId("M-" + UUID.randomUUID());
        message.basicProperties.setRoutingKey(routingKey);
        message.body = body;
        return message;
    }

为什么不用构造方法?

        使用构造方法也能达成同样目的,但是工厂方法可以让名字更清晰,毕竟工厂方法就是来填构造 方法不能随便取名字的坑。

4.序列化与反序列化

准备工作:实现一个Serializable接口(标记接口)

此处准备使用标准库自带的方式进行序列化和反序列化,为什么不使用Json方式?

Json的本质是文本格式

而此处的Message里面存储的是二进制

5.offsetBeg和offsetEnd

offsetBeg 和 offsetEnd 不需要序列化

1.此时消息被写入文件后 所在的位置固定 并不需要存储这两个属性

2.属性存在的目的:为了让内存中的Message对象, 能够快速找到对应的硬盘上的Message的位置

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

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

相关文章

aws平台s3存储桶夸域问题处理

当我们收到开发反馈s3存在跨域问题 解决步骤&#xff1a; 配置 S3 存储桶的 CORS 设置&#xff1a; 登录到 AWS 管理控制台。转到 S3 服务。选择你存储文件的 存储桶。点击 权限 标签页。在 跨域资源共享&#xff08;CORS&#xff09;配置 部分&#xff0c;点击 编辑。 登陆…

【vue-text-highlight】在vue2的使用教程

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、下载二、使用步骤1.引入库2.用法 效果速通 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 例如&#xff1a;随着人工智能的不断发…

pycharm无法正常调试问题

pycharm无法正常调试问题 1.错误代码 已连接到 pydev 调试器(内部版本号 231.8109.197)Traceback (most recent call last):File "E:\Python\pycharm\PyCharm 2023.1\plugins\python\helpers\pydev\_pydevd_bundle\pydevd_comm.py", line 304, in _on_runr r.deco…

Leetcode百题斩-哈希

看来面试前还是要老老实实刷leetcode为好&#xff0c;今天看到一个题库&#xff0c;leetcode百题斩&#xff0c;刚好最近面试的这两题全在里面。瞄了一眼&#xff0c;也有不少题之前居然也刷过。那么&#xff0c;冲冲冲&#xff0c;看多久能把这百题刷完。 第一天&#xff0c;先…

EXIST与JOIN连表比较

结论 1&#xff1a;EXIST可以用于链表&#xff0c;且可以利用到索引2&#xff1a;当join无法合理利用到索引&#xff0c;可以尝试EXIST链表3&#xff1a;EXIST在某些情况下可以更好地利用到索引4&#xff1a;大数据量时&#xff0c;要考虑EXIST的使用 EXIST SQL: EXPLAN JOIN…

【Linux】利用多路转接epoll机制、ET模式,基于Reactor设计模式实现

&#x1f4da; 博主的专栏 &#x1f427; Linux | &#x1f5a5;️ C | &#x1f4ca; 数据结构 | &#x1f4a1;C 算法 | &#x1f152; C 语言 | &#x1f310; 计算机网络 上篇文章&#xff1a;多路转接epoll&#xff0c;实现echoserver 至此&#xff0c;Linux与…

react中运行 npm run dev 报错,提示vite.config.js出现错误 @esbuild/win32-x64

在React项目中运行npm run dev时&#xff0c;如果遇到vite.config.js报错&#xff0c;提示esbuild/win32-x64在另一个平台中被使用&#xff0c;通常是由于依赖冲突或缓存问题导致的。解决方法是删除node_modules文件夹&#xff0c;并重新安装依赖。 如下图&#xff1a; 解决办…

鸿蒙UI开发——Builder与LocalBuilder对比

1、概 述 在ArkUI中&#xff0c;有的朋友应该接触过Builder和LocalBuilder。其中有了LocalBuilder的存在&#xff0c;是为了解决组件的父子关系和状态管理的父子关系保持一致的问题。 这里面最直观的表现则是this的指向问题与组件刷新问题&#xff0c;本文对Builder与LocalBu…

关于光谱相机的灵敏度

一、‌灵敏度的核心定义‌ ‌光谱灵敏度&#xff08;单色灵敏度&#xff09;‌ 描述光谱相机对单色辐射光的响应能力&#xff0c;即探测器对特定波长入射光的输出信号强度与入射光功率的比值。 例如&#xff0c;若在680nm波长下的光谱灵敏度较高&#xff0c;则表示该相机对此…

Model 速通系列(一)nanoGPT

这个是新开的一个系列用来手把手复现一些模型工程&#xff0c;之所以开这个系列是因为有人留言说看到一个工程不知道从哪里读起&#xff0c;出于对自身能力的提升与兴趣&#xff0c;故新开了这个系列。由于主要动机是顺一遍代码并提供注释。 该系列第一篇博客是 nanoGPT &…

MySQL--day4--排序与分页

&#xff08;以下内容全部来自上述课程&#xff09; 1. 排序数据 1.1 排序基本使用 #1.排序 #如果没有使用排序操作&#xff0c;默认情况下查询返回的数据是按照添加数据的顺序显示的 SELECT * FROM employees;# 练习:按照salary从高到低的顺序显示员工信息 # 使用 ORDER …

系分论文《论软件系统安全分析和应用》

系统分析师论文范文系列 【摘要】 2023年3月&#xff0c;我司承接了某知名电商企业“智能化供应链管理系统”的开发任务&#xff0c;我作为系统分析师负责全面的安全分析与设计工作。该系统以提升电商供应链效率为核心&#xff0c;整合仓储、物流、支付等模块&#xff0c;并需应…

Mac安装redis

1、 去往网址 http://​编download.​编redis.io/releases/ 找到任意 结尾为* .tar.gz的文件下载下来 2、使用终端进入下载下来的redis文件 3、直接执行redis-server 如果出现redis标志性的图代表成功 如果显示command not found :redis-server 则在终端再进入src文件夹下&…

srs-7.0 支持obs推webrtc流

demo演示 官方教程: https://ossrs.net/lts/zh-cn/blog/Experience-Ultra-Low-Latency-Live-Streaming-with-OBS-WHIP 实现原理就是通过WHIP协议来传输 SDP信息 1、运行 ./objs/srs -c conf/rtc.conf 2、obs推流 3、web端播放webrtc流 打开web:ht

Babylon.js学习之路《七、用户交互:鼠标点击、拖拽与射线检测》

文章目录 1. 引言&#xff1a;用户交互的核心作用1.1 材质与纹理的核心作用 2. 基础交互&#xff1a;鼠标与触摸事件2.1 绑定鼠标点击事件2.2 触摸事件适配 3. 射线检测&#xff08;Ray Casting&#xff09;3.1 射线检测的原理3.2 高级射线检测技巧 4. 拖拽物体的实现4.1 拖拽基…

星际争霸小程序:用Java实现策略模式的星际大战

在游戏开发的世界里&#xff0c;策略模式是一种非常实用的设计模式&#xff0c;它允许我们在运行时动态地选择算法或行为。今天&#xff0c;我将带你走进一场星际争霸的奇幻之旅&#xff0c;用Java实现一个简单的星际争霸小程序&#xff0c;通过策略模式来模拟不同种族单位的战…

Python数据可视化高级实战之一——绘制GE矩阵图

目录 一、课程概述 二、GE矩阵? 三、GE 矩阵图的适用范围 五、GE 矩阵的评估方法 (一)市场吸引力的评估要素 二、企业竞争实力的评估要素 三、评估方法与实践应用 1. 定量与定性结合法 2. 数据来源 六、GE矩阵的图形化实现 七、总结:GE 矩阵与 BCG 矩阵的对比分析 (一)GE…

StreamSaver实现大文件下载解决方案

StreamSaver实现大文件下载解决方案 web端 安装 StreamSaver.js npm install streamsaver # 或 yarn add streamsaver在 Vue 组件中导入 import streamSaver from "streamsaver"; // 确保导入名称正确完整代码修正 <!--* projectName: * desc: * author: dua…

CSS【详解】弹性布局 flex

适用场景 一维&#xff08;行或列&#xff09;布局 基本概念 包裹所有被布局元素的父元素为容器 所有被布局的元素为项目 项目的排列方向&#xff08;垂直/水平&#xff09;为主轴 与主轴垂直的方向交交叉轴 容器上启用 flex 布局 将容器的 display 样式设置为 flex 或 i…

自回归图像编辑 EditAR: Unified Conditional Generation with Autoregressive Models

Paperhttps://arxiv.org/pdf/2501.04699 Code (coming soon) 目录 方法 实验 EditAR是一个统一的自回归框架&#xff0c;用于各种条件图像生成任务——图像编辑、深度到图像、边缘到图像、分割到图像。 next-token预测的功效尚未被证明用于图像编辑。 EditAR主要构建在Ll…