学习笔记——Springboot中整合rabbitmq

一、添加rabbitmq依赖

Springboot为rabbitmq提供了starter,可以非常方便的引入依赖。

	<dependencies>
        <!--rabbitmq模块-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>
        <!--web模块-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--测试模块-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

二、基本流程

rabbitmq的一个完整的信息收发流程大概如下图这样。
在这里插入图片描述
消息在到达队列之前已经通过了binding的筛选,所以,如果在使用过程中发现消费者接收到了不正确的数据,第一步应该是检查绑定是否正确。

三、各个模式的交换机实例

1、Fanout

配置类,创建队列与交换机,并将它们绑定

@Configuration
public class RabbitFanoutConfig {

    public static final String FANOUT_NAME = "tianqicode-fanout";

    // 提供两个队列的bean
    @Bean
    Queue queueOne() {
        return new Queue("fanout-queue-one");
    }

    @Bean
    Queue queueTwo() {
        return new Queue("fanout-queue-two");
    }

    // 提供fanout交换机的bean
    @Bean
    FanoutExchange fanoutExchange() {
        // 第一个参数为交换机的名称,第二个参数为是否持久化(重启服务后仍存在), 第三个参数为规定时间未使用自动删除
        return new FanoutExchange(FANOUT_NAME, false, false);
    }

    // 将队列1绑定交换机
    @Bean
    Binding bindingOne() {
        return BindingBuilder.bind(queueOne()).to(fanoutExchange());
    }
    // 将队列2绑定交换机
    @Bean
    Binding bindingTwo() {
        return BindingBuilder.bind(queueTwo()).to(fanoutExchange());
    }
    
}

消费者类,监听队列

@Component
public class FanoutReceiver {

    // 添加消费者1,监听fanout-queue-one
    @RabbitListener(queues = "fanout-queue-one")
    public void handler1(String msg) {
        System.out.println("fanout-handler1>>>>>"+msg);
    }

    // 添加消费者2,监听fanout-queue-two
    @RabbitListener(queues = "fanout-queue-two")
    public void handler2(String msg) {
        System.out.println("fanout-handler2>>>>>"+msg);
    }

}

在测试类中写一个生产者

// fanout模式发送消息,发送给所有绑定此交换机的队列
    @Test
    public void testFanout() {
        // 第一个参数为交换机名称,第二个参数为routingKey,第三个参数为发送的消息
        rabbitTemplate.convertAndSend(RabbitFanoutConfig.FANOUT_NAME, null, "hello fanout");
    }
2、Direct

配置类

@Configuration
public class RabbitDirectConfig {
    public static final String DIRECT_NAME = "tianqicode-direct";

    // 创建队列
    @Bean
    Queue directQueueOne() {
        return new Queue("direct-queue-one");
    }

    @Bean
    Queue directQueueTwo() {
        return new Queue("direct-queue-two");
    }

    // 创建交换机
    @Bean
    DirectExchange directExchange() {
        return new DirectExchange(DIRECT_NAME, false, false);
    }

    // 绑定交换机并规定routingKey
    @Bean
    Binding directBindingOne() {
        return BindingBuilder.bind(directQueueOne()).to(directExchange()).with("direct1");
    }

    @Bean
    Binding directBindingTwo() {
        return BindingBuilder.bind(directQueueTwo()).to(directExchange()).with("direct2");
    }

}

消费者

@Component
public class DirectReceiver {

    // 监听队列
    @RabbitListener(queues = "direct-queue-one")
    public void directHandler1(String msg) {
        System.out.println("directHandler1>>>>>" + msg);
    }

    @RabbitListener(queues = "direct-queue-two")
    public void directHandler2(String msg) {
        System.out.println("directHandler2>>>>>" + msg);
    }

}

生产者

	// direct模式发送消息,然后根据指定的routingKey发送到队列
    @Test
    public void testDirect() {
        // 第一个参数为交换机名称,第二个参数为routingKey,第三个参数为发送的消息
        rabbitTemplate.convertAndSend(RabbitDirectConfig.DIRECT_NAME,"direct1","direct 1111");
        rabbitTemplate.convertAndSend(RabbitDirectConfig.DIRECT_NAME,"direct2","direct 2222");
    }
3、Topic

配置类

@Configuration
public class RabbitTopicConfig {

    public static final String TOPIC_NAME = "tianqicode-topic";

    // 创建队列
    @Bean
    Queue xiaomi() {
        return new Queue("xiaomi");
    }
    @Bean
    Queue huawei() {
        return new Queue("huawei");
    }
    @Bean
    Queue phone() {
        return new Queue("phone");
    }

    // 创建交换机
    @Bean
    TopicExchange topicExchange() {
        return new TopicExchange(TOPIC_NAME, false, false);
    }

    // 通过routingKey将队列绑定交换机
    @Bean
    Binding xiaomiBinding() {
        // xiaomi.# 代表订阅以xiaomi为前缀的所有消息
        // 若不慎将队列绑定为错误的主题,可以到管理页面删除
        return BindingBuilder.bind(xiaomi()).to(topicExchange()).with("xiaomi.#");
    }

    @Bean
    Binding huaweiBinding() {
        return BindingBuilder.bind(huawei()).to(topicExchange()).with("huawei.#");
    }

    @Bean
    Binding phoneBinding() {
        return BindingBuilder.bind(phone()).to(topicExchange()).with("#.phone.#");
    }
}

消费者

@Component
public class TopicReceiver {

    // 创建消费者
    @RabbitListener(queues = "xiaomi")
    public void xiaomiHandler(String msg) {
        System.out.println("xiaomiHandler>>>>>" + msg);
    }

    @RabbitListener(queues = "huawei")
    public void huaweiHandler(String msg) {
        System.out.println("huaweiHandler>>>>>" + msg);
    }

    @RabbitListener(queues = "phone")
    public void phoneHandler(String msg) {
        System.out.println("phoneHandler>>>>>>" + msg);
    }

}

生产者

    // topic模式发送消息,在根据绑定的主题发送到队列
    @Test
    public void testTopic() {

        rabbitTemplate.convertAndSend(RabbitTopicConfig.TOPIC_NAME, "xiaomi.phone.news", "小米将发布新机型信息");
//        rabbitTemplate.convertAndSend(RabbitTopicConfig.TOPIC_NAME, "xiaomi.weather", "今日多云");
        rabbitTemplate.convertAndSend(RabbitTopicConfig.TOPIC_NAME, "huawei.phone.news", "华为鸿蒙系统开源");
//        rabbitTemplate.convertAndSend(RabbitTopicConfig.TOPIC_NAME, "huawei.weather", "今日多云");
    }

四、测试一下

1、运行testFanout

控制台打印
在这里插入图片描述
所有的队列都收到了消息

2、运行testDirect

队列根据routingKey接收到了消息
在这里插入图片描述

3、运行testTopic

主题订阅方式,消息接收更加灵活
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值