RabbitMQ基础篇之Java客户端 基于注解声明队列交换机

打印 上一主题 下一主题

主题 1027|帖子 1027|积分 3081

1. 基于 Java Bean 声明队列、交换机和绑定关系

利用 Java Bean 方式声明队列、交换机及其绑定关系。这样做的长处是,项目启动时 Spring AMQP 会自动根据代码创建队列、交换机,并建立绑定关系。代码简便且自动化,适合大部分简单的设置需求。
问题: 利用 Java Bean 方式时,如果需要绑定多个 routing key,需要重复写绑定代码,导致设置类变得冗长,维护起来比较贫苦。



2. 案例:利用 Java 代码声明 Direct Exchange

在现实的项目中,我们需要删除现有的队列和交换机,然后重新用 Java 代码声明。以下是 Direct Exchange 声明的关键步骤:


  • 声明交换机(Exchange)
  1. @Bean
  2. public FanoutExchange directExchange() {
  3.     //return ExchangeBuilder.fanoutExchange("nhuan.direct").build();    // 方式一
  4.     return new FanoutExchange("nhuan.direct");  // 方式二
  5. }
复制代码



  • 声明队列(Queue)
  1. @Bean
  2. public Queue directQueue1() {
  3.     //return QueueBuilder.durable("direct.queue1").build(); // 方式一
  4.     return new Queue("direct.queue1");  // 方式二
  5. }
  6. @Bean
  7. public Queue directQueue2() {
  8.     //return QueueBuilder.durable("direct.queue2").build();
  9.     return new Queue("direct.queue2");
  10. }
复制代码



  • 队列与交换机的绑定(Binding)
  1. @Bean
  2. public Binding fanoutQueue1BindingRed(Queue directQueue1, DirectExchange directExchange) {
  3.     return BindingBuilder.bind(directQueue1).to(directExchange).with("red");
  4. }
  5. @Bean
  6. public Binding fanoutQueue1BindingBlue(Queue directQueue1, DirectExchange directExchange) {
  7.     return BindingBuilder.bind(directQueue1).to(directExchange).with("blue");
  8. }
  9. @Bean
  10. public Binding fanoutQueue2BindingRed(Queue fanoutQueue2, DirectExchange directExchange) {
  11.     return BindingBuilder.bind(fanoutQueue2).to(directExchange).with("red");
  12. }
  13. @Bean
  14. public Binding fanoutQueue2BindingYellow(Queue fanoutQueue2, DirectExchange directExchange) {
  15.     return BindingBuilder.bind(fanoutQueue2).to(directExchange).with("yellow");
  16. }
复制代码



  • 完备示例
  1. package com.itheima.consumer.config;
  2. import org.springframework.amqp.core.*;
  3. import org.springframework.context.annotation.Bean;
  4. import org.springframework.context.annotation.Configuration;
  5. @Configuration
  6. public class DirectConfiguration {
  7.     @Bean
  8.     public FanoutExchange directExchange() {
  9.         //return ExchangeBuilder.fanoutExchange("nhuan.direct").build();    // 方式一
  10.         return new FanoutExchange("nhuan.direct");  // 方式二
  11.     }
  12.     @Bean
  13.     public Queue directQueue1() {
  14.         //return QueueBuilder.durable("direct.queue1").build(); // 方式一
  15.         return new Queue("direct.queue1");  // 方式二
  16.     }
  17.     @Bean
  18.     public Binding fanoutQueue1BindingRed(Queue directQueue1, DirectExchange directExchange) {
  19.         return BindingBuilder.bind(directQueue1).to(directExchange).with("red");
  20.     }
  21.     @Bean
  22.     public Binding fanoutQueue1BindingBlue(Queue directQueue1, DirectExchange directExchange) {
  23.         return BindingBuilder.bind(directQueue1).to(directExchange).with("blue");
  24.     }
  25.     @Bean
  26.     public Queue directQueue2() {
  27.         //return QueueBuilder.durable("direct.queue2").build();
  28.         return new Queue("direct.queue2");
  29.     }
  30.     @Bean
  31.     public Binding fanoutQueue2BindingRed(Queue fanoutQueue2, DirectExchange directExchange) {
  32.         return BindingBuilder.bind(fanoutQueue2).to(directExchange).with("red");
  33.     }
  34.     @Bean
  35.     public Binding fanoutQueue2BindingYellow(Queue fanoutQueue2, DirectExchange directExchange) {
  36.         return BindingBuilder.bind(fanoutQueue2).to(directExchange).with("yellow");
  37.     }
  38. }
复制代码

问题:


  • 每增长一个绑定关系,就需要额外声明一个 **Binding**。
  • 对于多个绑定键(如 **red**, **blue**),需要重复创建绑定代码,导致类非常冗长。




3. 基于注解声明队列、交换机及绑定关系(优化方案)

为了简化上述问题,Spring AMQP 提供了一种基于注解的方式来声明队列、交换机和绑定关系。这样可以减少代码冗余,而且支持更多灵活的设置。注解在消息监听器中利用。

关键注解:


  • @RabbitListener - 用于声明消费者并指定队列。
  • @QueueBinding - 用于声明队列与交换机的绑定关系。
  • @Queue - 用于声明队列。
  • @Exchange - 用于声明交换机。
  • @Binding - 用于指定绑定关系和 routing key。



示例:
  1. @RabbitListener(bindings = @QueueBinding(
  2.     value = @Queue(name = "direct.queue1", durable = "true"),
  3.     exchange = @Exchange(name = "nhuan.direct", type = ExchangeTypes.DIRECT),
  4.     key = {"red", "blue"}
  5. ))
  6. public void listenDirectQueue1(String message) {
  7.     log.info("消费者1接收到 direct.queue1 的消息: " + message);
  8. }
  9. @RabbitListener(bindings = @QueueBinding(
  10.     value = @Queue(name = "direct.queue2", durable = "true"),
  11.     exchange = @Exchange(name = "nhuan.direct", type = ExchangeTypes.DIRECT),
  12.     key = {"red", "yellow"}
  13. ))
  14. public void listenDirectQueue2(String message) {
  15.     log.info("消费者2接收到 direct.queue2 的消息: " + message);
  16. }
复制代码

解释:


  • @RabbitListener 用来声明消费者。
  • @QueueBinding 用来声明队列与交换机的绑定关系,绑定关系中指定了交换机名称、类型(如 direct)和多个 binding key。
  • @Queue 用来声明队列的名称。
  • @Exchange 用来声明交换机的名称和类型。



优势:


  • 简化代码:不再需要为每个 binding key 创建多个 Binding 实例。
  • 支持多个绑定键:可以在 key 属性中传递一个数组,绑定多个 routing key。
  • 更简便:通过注解一次性声明队列、交换机及绑定关系。




4. 注解方式的优缺点对比

特性基于 Java Bean 声明基于注解声明设置简便性设置类较为冗长,需要为每个绑定声明多个 Binding 实例。设置简便,多个绑定键通过数组一次性完成。代码维护性随着绑定键的增长,代码复杂度增大。注解方式更直观,易于维护。灵活性灵活,可通过 Java 代码灵活设置队列和交换机。灵活性较低,但对于简单场景更为实用。自动创建自动创建队列和交换机,减少手动操作。同样可以自动创建队列和交换机。
5. 总结与选择



  • 基于 Java Bean 声明:适合复杂的设置场景,需要灵活控制交换机、队列和绑定的参数。
  • 基于注解声明:适合简单的绑定设置,代码更加简便和易维护,特别是在绑定键数目较少时。


    开发中选择利用哪种方式
  • 可以根据项目需求和个人喜好选择利用 Java Bean 或注解方式。注解方式在简单场景下非常方便,但在复杂场景下,Java Bean 方式提供了更多的控制和灵活性。



6. 实践演示

启动项目后,自动创建了交换机、队列及绑定关系,并成功处理了消息。






免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

科技颠覆者

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表