zoukankan      html  css  js  c++  java
  • SpringBoot整合RabbitMQ之Topic主题交换器

    RabbitMQ中的Topic主题交换器:

    Topic交换器是主题模式,通过模式匹配分发消息的路由键属性,将路由键和某种模式进行匹配,此时队列需要绑定一种模式,Topic交换器将路由键和绑定的字符串切分成单词,这些单词直接用点“.”隔开。该交换器会识别两个通配符:“#”和“*”,其中“#”匹配0个或多个单词,“*”匹配不多不少一个单词。

    以下案例为实现Topic主题交换器的过程,本案例在上一章的基础之上编写的,需要这两个项目:rabbitmq-provider (生产者),一个rabbitmq-consumer(消费者)。

    首先在rabbitmq-provider项目上创建 TopicRabbitConfig配置类

    package com.rabbitmq.provider.config;
    
    import org.springframework.amqp.core.Binding;
    import org.springframework.amqp.core.BindingBuilder;
    import org.springframework.amqp.core.Queue;
    import org.springframework.amqp.core.TopicExchange;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    
    @Configuration
    public class TopicRabbitConfig {
    
        // 绑定键
        private final String man = "topic.man";
        private final String woman = "topic.women";
    
        @Bean
        Queue firstQueue() {
            return new Queue(man);
        }
    
        @Bean
        Queue secondQueue() {
            return new Queue(woman);
        }
    
        @Bean
        TopicExchange exchange(){
            return new TopicExchange("topicExchange");
        }
    
        //将firstQueue和topicExchange绑定,而且绑定的键值为topic.man
        //这样只要是消息携带的路由键是topic.man,才会分发到该队列
        @Bean
        Binding bindingExchangeMessage(){
            return BindingBuilder.bind(firstQueue()).to(exchange()).with(man);
        }
    
        //将secondQueue和topicExchange绑定,而且绑定的键值为用上通配路由键规则topic.#
        // 这样只要是消息携带的路由键是以topic.开头,都会分发到该队列
        @Bean
        Binding bindingExchangeMessage2(){
            return BindingBuilder.bind(secondQueue()).to(exchange()).with("topic.#");
        }
    }

    然后在Controller里面多加两个接口

        @GetMapping("/sendTopicMessage1")
        public String sendTopicMessage1() {
            String messageId = String.valueOf(UUID.randomUUID());
            String messageData = "message: M A N ";
            String createTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            Map<String, Object> manMap = new HashMap<>();
            manMap.put("messageId", messageId);
            manMap.put("messageData", messageData);
            manMap.put("createTime", createTime);
            rabbitTemplate.convertAndSend("topicExchange", "topic.man", manMap);
            return "ok";
        }
    
        @GetMapping("/sendTopicMessage2")
        public String sendTopicMessage2() {
            String messageId = String.valueOf(UUID.randomUUID());
            String messageData = "message: woman is all ";
            String createTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            Map<String, Object> womanMap = new HashMap<>();
            womanMap.put("messageId", messageId);
            womanMap.put("messageData", messageData);
            womanMap.put("createTime", createTime);
            rabbitTemplate.convertAndSend("topicExchange", "topic.woman", womanMap);
            return "ok";
        }

    生产者这边的操作已经完成,接下来去rabbitmq-consumer项目上编写后续代码

    创建TopicManReceiver

    package com.rabbitmq.consumer.receiver;
    
    import org.springframework.amqp.rabbit.annotation.RabbitHandler;
    import org.springframework.amqp.rabbit.annotation.RabbitListener;
    import org.springframework.stereotype.Component;
    
    import java.util.Map;
    
    
    @Component
    @RabbitListener(queues = "topic.man")
    public class TopicManReceiver {
    
        @RabbitHandler
        public void process(Map message){
            System.out.println("TopicManReceiver消费者收到消息 = " + message.toString());
        }
    }

    创建TopicWoManReceiver

    package com.rabbitmq.consumer.receiver;
    
    import org.springframework.amqp.rabbit.annotation.RabbitHandler;
    import org.springframework.amqp.rabbit.annotation.RabbitListener;
    import org.springframework.stereotype.Component;
    
    import java.util.Map;
    
    
    @Component
    @RabbitListener(queues = "topic.woman")
    public class TopicWoManReceiver {
    
        @RabbitHandler
        public void process(Map message) {
            System.out.println("TopicWoManReceiver消费者收到消息 = " + message);
        }
    }

    创建TopicRabbitConfig配置类

    package com.rabbitmq.consumer.config;
    
    import org.springframework.amqp.core.Binding;
    import org.springframework.amqp.core.BindingBuilder;
    import org.springframework.amqp.core.Queue;
    import org.springframework.amqp.core.TopicExchange;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class TopicRabbitConfig {
        //绑定键
        public final static String man = "topic.man";
        public final static String woman = "topic.woman";
    
        @Bean
        public Queue firstQueue() {
            return new Queue(TopicRabbitConfig.man);
        }
    
        @Bean
        public Queue secondQueue() {
            return new Queue(TopicRabbitConfig.woman);
        }
    
        @Bean
        TopicExchange exchange() {
            return new TopicExchange("topicExchange");
        }
    
    
        //将firstQueue和topicExchange绑定,而且绑定的键值为topic.man
        //这样只要是消息携带的路由键是topic.man,才会分发到该队列
        @Bean
        Binding bindingExchangeMessage() {
            return BindingBuilder.bind(firstQueue()).to(exchange()).with(man);
        }
    
        //将secondQueue和topicExchange绑定,而且绑定的键值为用上通配路由键规则topic.#
        // 这样只要是消息携带的路由键是以topic.开头,都会分发到该队列
        @Bean
        Binding bindingExchangeMessage2() {
            return BindingBuilder.bind(secondQueue()).to(exchange()).with("topic.#");
        }
    
    }

    然后把这两个项目跑起来,使用postman工具调用/sendTopicMessage1接口

    再调用/sendTopicMessage2接口

     

     可以看到,sendTopicMessage1调用的时候

    man和woman都消费到了信息,因为它们使用的是主题交换机,而woman绑定的路由是topic.#,“#”匹配0个或多个单词,所以woman能消费到这个接口的信息

    当调用sendTopicMessage2的时候,

    man消费不到woman的信息,因为man的路由是topic.man,只能消费topic.man的信息。

  • 相关阅读:
    求阴影部分的面积
    论语(原文注音, 注释, 译文, 评析) 打印版
    生肖故事
    北京大学2019年高等代数考研试题
    LaTeX技巧561:LaTeX如何让每一章带有目录?
    用 Mathematica 获取图片的 RGB 三基色
    tex 进度条
    跟锦数学190314
    Beamer 目录分栏
    Beamer 跳到另外一页
  • 原文地址:https://www.cnblogs.com/liweixml/p/14662040.html
Copyright © 2011-2022 走看看