当前位置: 首页 > article >正文

RabbitMQ中的@Header

在 RabbitMQ 中,@Header 是 Spring AMQP 提供的一种注解,用于从消息的 Headers 中提取特定的属性或元数据。通过 @Header,开发者可以方便地获取消息的附加信息(如路由键、消息标签、自定义头等),而无需手动解析消息的完整结构。

以下是对 @Header 的原理机制和用法的详细说明:


1. @Header 的作用

@Header 注解用于从消息的 Headers 中提取指定的属性值,并将其注入到方法参数中。它通常用于以下场景:

  • 获取消息的元数据(如 deliveryTagroutingKey 等)。
  • 获取自定义的 Header 值。
  • 获取死信队列的附加信息(如 x-death)。

2. @Header 的原理

在 Spring AMQP 中,@Header 的工作原理如下:

  1. 消息接收
    当消费者接收到消息时,Spring AMQP 会将消息的 Headers 解析为一个 Map<String, Object> 结构。
  2. 参数绑定
    在方法调用时,Spring AMQP 会根据 @Header 注解指定的名称,从 Headers 中提取对应的值,并将其绑定到方法参数上。
  3. 类型转换
    Spring AMQP 会自动将提取的值转换为方法参数的类型(如 StringLongList 等)。

3. @Header 的用法

(1)获取内置 Header

RabbitMQ 消息的 Headers 中包含一些内置属性,可以通过 @Header 直接获取。例如:

  • AmqpHeaders.DELIVERY_TAG:消息的唯一标识(deliveryTag),用于手动确认消息。
  • AmqpHeaders.RECEIVED_ROUTING_KEY:消息的路由键。
  • AmqpHeaders.CONSUMER_QUEUE:消息所在的队列名称。

示例

@RabbitHandler
public void onMessage(String message, 
                      @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag, 
                      @Header(AmqpHeaders.RECEIVED_ROUTING_KEY) String routingKey) {
    System.out.println("Received message: " + message);
    System.out.println("Delivery tag: " + deliveryTag);
    System.out.println("Routing key: " + routingKey);
}
(2)获取自定义 Header

如果消息中包含自定义的 Header,可以通过 @Header 提取。

示例

@RabbitHandler
public void onMessage(String message, 
                      @Header("custom-header") String customHeader) {
    System.out.println("Received message: " + message);
    System.out.println("Custom header: " + customHeader);
}
(3)获取死信队列的 x-death 信息

当消息被转发到死信队列时,RabbitMQ 会在 Headers 中添加 x-death 属性,记录消息的死信原因和原始队列信息。

示例

@RabbitHandler
public void onAmusementMsg(String message, 
                           @Header("x-death") List<Map<String, Object>> death) {
    System.out.println("Received dead letter message: " + message);
    if (death != null) {
        for (Map<String, Object> deathRecord : death) {
            System.out.println("Death reason: " + deathRecord.get("reason"));
            System.out.println("Original queue: " + deathRecord.get("queue"));
        }
    }
}

4. x-death 的结构

x-death 是一个 List<Map<String, Object>> 结构,每个 Map 代表一条死信记录。常见的字段包括:

  • reason:死信原因(如 expiredrejected 等)。
  • queue:原始队列名称。
  • exchange:原始交换机名称。
  • routing-keys:原始路由键。
  • time:消息死亡时间。

示例 x-death 内容

[
  {
    "reason": "expired",
    "queue": "order.queue",
    "exchange": "order.exchange",
    "routing-keys": ["order.create"],
    "time": "2023-10-01T12:00:00Z"
  }
]

5. 注意事项

  • Header 名称区分大小写
    确保 @Header 注解中的名称与消息 Header 中的名称完全一致。
  • 默认值
    如果指定的 Header 不存在,方法参数会设置为 null。可以通过 @Header(name = "headerName", required = false) 设置非必填。
  • 类型匹配
    确保方法参数的类型与 Header 值的类型兼容,否则会抛出类型转换异常。

6. 完整示例

以下是一个完整的示例,展示如何使用 @Header 获取消息的 deliveryTagx-death 信息:

@RabbitListener(queues = "myQueue")
public class MyMessageListener {

    @RabbitHandler
    public void onAmusementMsg(String message, 
                               Channel channel, 
                               @Header(AmqpHeaders.DELIVERY_TAG) long tag, 
                               @Header("x-death") List<Map<String, Object>> death) {
        try {
            System.out.println("Received message: " + message);
            System.out.println("Delivery tag: " + tag);

            if (death != null) {
                for (Map<String, Object> deathRecord : death) {
                    System.out.println("Death reason: " + deathRecord.get("reason"));
                    System.out.println("Original queue: " + deathRecord.get("queue"));
                }
            }

            // 手动确认消息
            channel.basicAck(tag, false);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

总结

  • @Header 是 Spring AMQP 提供的一种便捷方式,用于从消息的 Headers 中提取元数据或自定义属性。
  • 通过 @Header,可以轻松获取消息的 deliveryTagroutingKeyx-death 等信息。
  • 结合 @RabbitHandler@RabbitListener,可以实现灵活的消息处理逻辑。

通过合理使用 @Header,可以简化代码并提高消息处理的灵活性和可维护性。


http://www.kler.cn/a/533293.html

相关文章:

  • 网络爬虫会对服务器造成哪些影响?
  • 物联网领域的MQTT协议,优势和应用场景
  • 冰蝎v4.0.5 来啦
  • git进阶--6---git stash
  • Go学习:类型转换需注意的点 以及 类型别名
  • Maven jar 包下载失败问题处理
  • Maven 依赖管理基础
  • 网络命令
  • Java并发编程面试题:ThreadLocal(8题)
  • windows 剪切板的写入、读取,包括图片,文本内容
  • 代码随想录二刷|回溯1
  • 嵌入式开发:PPM是什么单位
  • 基础篇05-直方图操作
  • 深度整理总结MySQL——Count的工作原理
  • Swagger相关内容整合
  • 【实用小技巧】git如何添加一个文件的一部分修改到暂存区(git add -p)
  • 深入理解 JavaScript 的 Promise:实例方法与静态方法
  • 无法连接到远程扩展主机服务器
  • 如何解决 Vue 应用中的内存泄漏
  • css 之 clip-path
  • 本地大模型编程实战(08)自制聊天机器人(2)
  • Java 常见的面试题(Hibernate)
  • 基于SpringBoot浪狼狗领养系统
  • C++多线程编程——call_once和单例模式
  • 【AI日记】25.02.05 自由不是一种工具
  • 2025年2月4日--2月9日(ue4.0shader抄写+ue5肉鸽独立游戏视频)