• RabbitMQ中java实现队列和交换机的声明


    java实现队列和交换机的声明

    在之前我们都是基于RabbitMQ控制台来创建队列、交换机。但是在实际开发时,队列和交换机是程序员定义的,将来项目上线,又要交给运维去创建。那么程序员就需要把程序中运行的所有队列和交换机都写下来,交给运维。在这个过程中是很容易出现错误的。
    因此推荐的做法是由程序启动时检查队列和交换机是否存在,如果不存在自动创建。

    在这里插入图片描述

    3.8.1.基本API

    SpringAMQP提供了一个Queue类,用来创建队列:
    image.png

    SpringAMQP还提供了一个Exchange接口,来表示所有不同类型的交换机:
    image.png
    在这里插入图片描述
    我们可以自己创建队列和交换机,不过SpringAMQP还提供了ExchangeBuilder来简化这个过程:
    image.png
    而在绑定队列和交换机时,则需要使用BindingBuilder来创建Binding对象:
    image.png

    3.8.2.fanout示例(基于Bean声明)

    在这里插入图片描述

    在consumer中创建一个类,声明队列和交换机:

    package com.itheima.consumer.config;
    
    import org.springframework.amqp.core.Binding;
    import org.springframework.amqp.core.BindingBuilder;
    import org.springframework.amqp.core.FanoutExchange;
    import org.springframework.amqp.core.Queue;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class FanoutConfig {
        /**
         * 声明交换机
         * @return Fanout类型交换机
         */
        @Bean
        public FanoutExchange fanoutExchange(){
            return new FanoutExchange("hmall.fanout");
        }
    
        /**
         * 第1个队列
         */
        @Bean
        public Queue fanoutQueue1(){
            return new Queue("fanout.queue1");
        }
    
        /**
         * 绑定队列和交换机
         */
        @Bean
        public Binding bindingQueue1(Queue fanoutQueue1, FanoutExchange fanoutExchange){
            return BindingBuilder.bind(fanoutQueue1).to(fanoutExchange);
        }
    
        /**
         * 第2个队列
         */
        @Bean
        public Queue fanoutQueue2(){
            return new Queue("fanout.queue2");
        }
    
        /**
         * 绑定队列和交换机
         */
        @Bean
        public Binding bindingQueue2(Queue fanoutQueue2, FanoutExchange fanoutExchange){
            return BindingBuilder.bind(fanoutQueue2).to(fanoutExchange);
        }
    }
    

    实际测试:

    在这里插入图片描述

    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 FanoutConfiguration {
    
        /**
         * 声明fanout类型交换机
         * @return
         */
        @Bean
        public FanoutExchange fanoutExchange(){
            // 两种声明方法都可以
            // return ExchangeBuilder.fanoutExchange("hmall.fanout2").build();
            return new FanoutExchange("hmall.fanout2");
        }
    
        /**
         * 声明默认持久化的fanout.queue3队列
         * @return
         */
        @Bean
        public Queue fanoutQueue3(){
            // 两种声明方法都可以
            // return QueueBuilder.durable("fanout.queue3").build();
            return new Queue("fanout.queue3");
        }
    
        /**
         * 绑定队列和交换机
         * @param fanoutExchange
         * @param fanoutQueue3
         * @return
         */
        @Bean
        public Binding fanoutBinding3(FanoutExchange fanoutExchange,Queue fanoutQueue3){
            return BindingBuilder.bind(fanoutQueue3).to(fanoutExchange);
    
        }
    
        /**
         * 声明默认持久化的fanout.queue4队列
         * @return
         */
        @Bean
        public Queue fanoutQueue4(){
            // 两种声明方法都可以
             return QueueBuilder.durable("fanout.queue4").build();
    //        return new Queue("fanout.queue4");
        }
    
    
        /**
         * 绑定队列和交换机
         * @return
         */
        @Bean
        public Binding fanoutBinding4(){
            return BindingBuilder.bind(fanoutQueue4()).to(fanoutExchange());
    
        }
    }
    
    

    3.8.2.direct示例(基于Bean声明)

    direct模式由于要绑定多个KEY,会非常麻烦,每一个Key都要编写一个binding:

    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 DirectConfig {
    
        /**
         * 声明交换机
         * @return Direct类型交换机
         */
        @Bean
        public DirectExchange directExchange(){
            return ExchangeBuilder.directExchange("hmall.direct").build();
        }
    
        /**
         * 第1个队列
         */
        @Bean
        public Queue directQueue1(){
            return new Queue("direct.queue1");
        }
    
        /**
         * 绑定队列和交换机
         */
        @Bean
        public Binding bindingQueue1WithRed(Queue directQueue1, DirectExchange directExchange){
            return BindingBuilder.bind(directQueue1).to(directExchange).with("red");
        }
        /**
         * 绑定队列和交换机
         */
        @Bean
        public Binding bindingQueue1WithBlue(Queue directQueue1, DirectExchange directExchange){
            return BindingBuilder.bind(directQueue1).to(directExchange).with("blue");
        }
    
        /**
         * 第2个队列
         */
        @Bean
        public Queue directQueue2(){
            return new Queue("direct.queue2");
        }
    
        /**
         * 绑定队列和交换机
         */
        @Bean
        public Binding bindingQueue2WithRed(Queue directQueue2, DirectExchange directExchange){
            return BindingBuilder.bind(directQueue2).to(directExchange).with("red");
        }
        /**
         * 绑定队列和交换机
         */
        @Bean
        public Binding bindingQueue2WithYellow(Queue directQueue2, DirectExchange directExchange){
            return BindingBuilder.bind(directQueue2).to(directExchange).with("yellow");
        }
    }
    
    

    3.8.4.基于注解声明

    基于@Bean的方式声明队列和交换机比较麻烦,Spring还提供了基于注解方式来声明。

    注意声明的文件是Listener下的,在监听者位置声明

    在这里插入图片描述

    例如,我们同样声明Direct模式的交换机和队列:

    @RabbitListener(bindings = @QueueBinding(
        value = @Queue(name = "direct.queue1"),
        exchange = @Exchange(name = "hmall.direct", type = ExchangeTypes.DIRECT),
        key = {"red", "blue"}
    ))
    public void listenDirectQueue1(String msg){
        System.out.println("消费者1接收到direct.queue1的消息:【" + msg + "】");
    }
    
    @RabbitListener(bindings = @QueueBinding(
        value = @Queue(name = "direct.queue2"),
        exchange = @Exchange(name = "hmall.direct", type = ExchangeTypes.DIRECT),
        key = {"red", "yellow"}
    ))
    public void listenDirectQueue2(String msg){
        System.out.println("消费者2接收到direct.queue2的消息:【" + msg + "】");
    }
    

    是不是简单多了。
    再试试Topic模式:

    @RabbitListener(bindings = @QueueBinding(
        value = @Queue(name = "topic.queue1"),
        exchange = @Exchange(name = "hmall.topic", type = ExchangeTypes.TOPIC),
        key = "china.#"
    ))
    public void listenTopicQueue1(String msg){
        System.out.println("消费者1接收到topic.queue1的消息:【" + msg + "】");
    }
    
    @RabbitListener(bindings = @QueueBinding(
        value = @Queue(name = "topic.queue2"),
        exchange = @Exchange(name = "hmall.topic", type = ExchangeTypes.TOPIC),
        key = "#.news"
    ))
    public void listenTopicQueue2(String msg){
        System.out.println("消费者2接收到topic.queue2的消息:【" + msg + "】");
    }
    

    小结

    在这里插入图片描述

  • 相关阅读:
    代理模式简单举例
    《乔布斯传》英文原著重点词汇笔记(一)【 Introduction 】
    Moebius数据库多活集群
    【软件逆向-基础知识】分析方法、汇编指令体系结构
    作业-11.9
    数字IC/FPGA——锁存器/触发器/寄存器
    Python在工业自动化领域的应用详解
    Qt 综合练习小项目--反金币(2/2)
    科技云报道:分布式存储红海中,看天翼云HBlock如何突围?
    ChatGPT | Bing | Google Bard | 讯飞星火 | 到底哪家强?实测
  • 原文地址:https://blog.csdn.net/2302_79020600/article/details/140045087