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

文章目录

        • [1. 基于 Java Bean 声明队列、交换机和绑定关系](#1. 基于 Java Bean 声明队列、交换机和绑定关系)
        • [2. 案例:使用 Java 代码声明 Direct Exchange](#2. 案例:使用 Java 代码声明 Direct Exchange)
        • [3. 基于注解声明队列、交换机及绑定关系(优化方案)](#3. 基于注解声明队列、交换机及绑定关系(优化方案))
        • [4. 注解方式的优缺点对比](#4. 注解方式的优缺点对比)
        • [5. 总结与选择](#5. 总结与选择)
        • [6. 实践演示](#6. 实践演示)
1. 基于 Java Bean 声明队列、交换机和绑定关系

使用 Java Bean 方式声明队列、交换机及其绑定关系。这样做的好处是,项目启动时 Spring AMQP 会自动根据代码创建队列、交换机,并建立绑定关系。代码简洁且自动化,适合大部分简单的配置需求。

问题: 使用 Java Bean 方式时,如果需要绑定多个 routing key,需要重复写绑定代码,导致配置类变得冗长,维护起来比较麻烦。

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

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

  • 声明交换机(Exchange)
java 复制代码
@Bean
public FanoutExchange directExchange() {
    //return ExchangeBuilder.fanoutExchange("nhuan.direct").build();    // 方式一
    return new FanoutExchange("nhuan.direct");  // 方式二
}
  • 声明队列(Queue)
java 复制代码
@Bean
public Queue directQueue1() {
    //return QueueBuilder.durable("direct.queue1").build(); // 方式一
    return new Queue("direct.queue1");  // 方式二
}

@Bean
public Queue directQueue2() {
    //return QueueBuilder.durable("direct.queue2").build();
    return new Queue("direct.queue2");
}
  • 队列与交换机的绑定(Binding)
java 复制代码
@Bean
public Binding fanoutQueue1BindingRed(Queue directQueue1, DirectExchange directExchange) {
    return BindingBuilder.bind(directQueue1).to(directExchange).with("red");
}

@Bean
public Binding fanoutQueue1BindingBlue(Queue directQueue1, DirectExchange directExchange) {
    return BindingBuilder.bind(directQueue1).to(directExchange).with("blue");
}


@Bean
public Binding fanoutQueue2BindingRed(Queue fanoutQueue2, DirectExchange directExchange) {
    return BindingBuilder.bind(fanoutQueue2).to(directExchange).with("red");
}

@Bean
public Binding fanoutQueue2BindingYellow(Queue fanoutQueue2, DirectExchange directExchange) {
    return BindingBuilder.bind(fanoutQueue2).to(directExchange).with("yellow");
}
  • 完整示例
java 复制代码
package com.itheima.consumer.config;

import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class DirectConfiguration {

    @Bean
    public FanoutExchange directExchange() {
        //return ExchangeBuilder.fanoutExchange("nhuan.direct").build();    // 方式一
        return new FanoutExchange("nhuan.direct");  // 方式二
    }

    @Bean
    public Queue directQueue1() {
        //return QueueBuilder.durable("direct.queue1").build(); // 方式一
        return new Queue("direct.queue1");  // 方式二
    }

    @Bean
    public Binding fanoutQueue1BindingRed(Queue directQueue1, DirectExchange directExchange) {
        return BindingBuilder.bind(directQueue1).to(directExchange).with("red");
    }

    @Bean
    public Binding fanoutQueue1BindingBlue(Queue directQueue1, DirectExchange directExchange) {
        return BindingBuilder.bind(directQueue1).to(directExchange).with("blue");
    }

    @Bean
    public Queue directQueue2() {
        //return QueueBuilder.durable("direct.queue2").build();
        return new Queue("direct.queue2");
    }

    @Bean
    public Binding fanoutQueue2BindingRed(Queue fanoutQueue2, DirectExchange directExchange) {
        return BindingBuilder.bind(fanoutQueue2).to(directExchange).with("red");
    }

    @Bean
    public Binding fanoutQueue2BindingYellow(Queue fanoutQueue2, DirectExchange directExchange) {
        return BindingBuilder.bind(fanoutQueue2).to(directExchange).with("yellow");
    }
}

问题:

  • 每增加一个绑定关系,就需要额外声明一个 **Binding**
  • 对于多个绑定键(如 **red**, **blue**),需要重复创建绑定代码,导致类非常冗长。
3. 基于注解声明队列、交换机及绑定关系(优化方案)

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

关键注解:

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

示例:

java 复制代码
@RabbitListener(bindings = @QueueBinding(
    value = @Queue(name = "direct.queue1", durable = "true"),
    exchange = @Exchange(name = "nhuan.direct", type = ExchangeTypes.DIRECT),
    key = {"red", "blue"}
))
public void listenDirectQueue1(String message) {
    log.info("消费者1接收到 direct.queue1 的消息: " + message);
}

@RabbitListener(bindings = @QueueBinding(
    value = @Queue(name = "direct.queue2", durable = "true"),
    exchange = @Exchange(name = "nhuan.direct", type = ExchangeTypes.DIRECT),
    key = {"red", "yellow"}
))
public void listenDirectQueue2(String message) {
    log.info("消费者2接收到 direct.queue2 的消息: " + message);
}

解释:

  • @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. 实践演示

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

相关推荐
坐吃山猪2 小时前
SpringBoot01-配置文件
java·开发语言
我叫汪枫3 小时前
《Java餐厅的待客之道:BIO, NIO, AIO三种服务模式的进化》
java·开发语言·nio
yaoxtao3 小时前
java.nio.file.InvalidPathException异常
java·linux·ubuntu
Swift社区4 小时前
从 JDK 1.8 切换到 JDK 21 时遇到 NoProviderFoundException 该如何解决?
java·开发语言
DKPT5 小时前
JVM中如何调优新生代和老生代?
java·jvm·笔记·学习·spring
phltxy5 小时前
JVM——Java虚拟机学习
java·jvm·学习
seabirdssss7 小时前
使用Spring Boot DevTools快速重启功能
java·spring boot·后端
喂完待续7 小时前
【序列晋升】29 Spring Cloud Task 微服务架构下的轻量级任务调度框架
java·spring·spring cloud·云原生·架构·big data·序列晋升
benben0447 小时前
ReAct模式解读
java·ai