springAMQP-模糊匹配(topic)模式

2022-07-25,,,

package com.example.demo.framework.mq;

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

/**
 * 模糊匹配
 * 定义路由键匹配规则
 * a.b.c
 * a表示性别  boy男,gril女
 * b表示国籍  中国china , 美国us , 英国ua
 * c表示爱好  sing唱歌 dancing跳舞
 * 实例 爱唱歌的中国男 boy.china.sing
 *     中国人         *.china.*
 *     男人          boy.*.* || boy.#
 *     *(星号)可以代替一个单词。
 *     #(哈希)可以替代零个或多个单词。
 */
@Configuration
public class MqTopic {
    /** 交换机名称 */
    public static String Exchange_Name = "topicExchange";
    /** 队列名称  */
    public static String Queue_Name1 = "topic1";
    /** 队列名称  */
    public static String Queue_Name2 = "topic2";
    /** 队列名称  */
    public static String Queue_Name3 = "topic3";
    /** 批量队列名称  */
    public static String Queue_Batch_Name = "topicQueueBatch";

    /** 路由键 */
    public static String Rout_key1 = "*.china.*";
    public static String Rout_key2 = "boy.#";
    public static String Rout_key3 = "#.sing";
    public static String Rout_key_Batch = "topic.batch";

    /**
     * 声明队列
     * @return
     */
    @Bean
    Queue myQueue1() {
        return new Queue(Queue_Name1);
    }
    @Bean
    Queue myQueue2() {
        return new Queue(Queue_Name2);
    }
    @Bean
    Queue myQueue3() {
        return new Queue(Queue_Name3);
    }
    @Bean
    Queue batchQueueTopic() {
        return new Queue(Queue_Batch_Name);
    }

    /**
     * SpringAMQP 提供了各种类型的交换机类型
     * DirectExchange  1v1队列
     * FanoutExchange  广播模式
     * HeadersExchange  头模式 不是很了解这个模式
     * TopicExchange   模糊匹配模式 正在使用
     * @return
     */
    @Bean
    TopicExchange bindTopicExchange(){
        /**
         * 构造一个新的Exchange,并为其指定名称,持久性标志和自动删除标志以及*参数。
         * @param name 交换的名称。
         * @param durable 如果我们声明一个持久交换(交换将在服务器重启后保留),则为true
         * @param autoDelete 如果服务器在不再使用该交换时应删除该交换,则为true
         * @param arguments 用于声明交换的参数
         */
        return new TopicExchange(Exchange_Name,false,true,null);
    }

    /**
     * 将交换机与队列绑定同时设置路由键
     * @return
     */
    @Bean
    Binding topicBindingOne(){
        return BindingBuilder.bind(myQueue3()).to(bindTopicExchange()).with(Rout_key3);
    }
    @Bean
    Binding topicBindingtwo(){
        return BindingBuilder.bind(myQueue2()).to(bindTopicExchange()).with(Rout_key2);
    }
    @Bean
    Binding topicBindingthere(){
        return BindingBuilder.bind(myQueue1()).to(bindTopicExchange()).with(Rout_key1);

    }
    @Bean
    Binding topicBindingBatch(){
        return BindingBuilder.bind(batchQueueTopic()).to(bindTopicExchange()).with(Rout_key_Batch);
    }
}

举个例子:一个会接收带中国标志的消息队列 一个会接收带唱歌的消息队列 一个会接收带男性的消息队列,通过声明需要某种标签的队列来接收对应标签的消息
先说下规则

 * a.b.c
 * a表示性别  boy男,gril女
 * b表示国籍  中国china , 美国us , 英国ua
 * c表示爱好  sing唱歌 dancing跳舞
 * 实例 爱唱歌的中国男 boy.china.sing
 *     中国人         *.china.*
 *     男人          boy.*.* || boy.#
 *     *(星号)可以代替一个单词。
 *     #(哈希)可以替代零个或多个单词。

模糊匹配的主要是指定好路由键 模糊匹配是根据路由键来匹配的
交换机和队列只是个绑定关系 真正的路由模糊匹配是路由键的原因
你可以定义多个队列来绑定不同消息标签的路由键 从而实现不同的队列接收不同类型的消息

示例:定义一个接收带男人标签的队列

//模糊匹配带男人的消息
 @Bean
    Binding topicBindingOne(){
        return BindingBuilder.bind(new Queue("boyQueue")).to(new TopicExchange("boy_exchange",false,true,null)).with("boy.#");
    }

消息监听

package com.example.demo.modules.rabbitMQ;


import com.example.demo.framework.mq.MqDirect;
import com.sun.istack.internal.logging.Logger;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.util.List;

@Component
public class MQListener {

    private Logger log = Logger.getLogger(MQListener.class);


    /**
     * 中国
     * @param msg
     */
    @RabbitListener(queues = "topic1")
    public void topic1(String msg){
        log.info("topic1监听到的消息--中国--->"+msg);
    }

    /**
     * 男
     * @param msg
     */
    @RabbitListener(queues = "topic2")
    public void topic2(String msg){
        log.info("topic2监听到的消息--男--->"+msg);
    }

    /**
     * 唱歌
     * @param msg
     */
    @RabbitListener(queues = "topic3")
    public void topic3(String msg){
        log.info("topic3监听到的消息--唱歌--->"+msg);
    }
}

发送消息

package com.example.demo;

import com.example.demo.framework.mq.MqDirect;
import com.example.demo.framework.mq.MqFanout;
import com.example.demo.framework.mq.MqTopic;
import com.rabbitmq.client.Channel;
import org.junit.jupiter.api.Test;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.connection.Connection;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.BatchingRabbitTemplate;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.io.IOException;

@SpringBootTest
class RabbmitMqApplicationTests {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Test
    void topic(){
        //中国人
        rabbitTemplate.convertAndSend
                (MqTopic.Exchange_Name,"boy.china.sing",getMsg("男","中国","唱歌"));
        rabbitTemplate.convertAndSend
                (MqTopic.Exchange_Name,"girl.china.dancing",getMsg("女","中国","跳舞"));
        //唱歌的人
        rabbitTemplate.convertAndSend
                (MqTopic.Exchange_Name,"girl.us.sing",getMsg("女","美国","唱歌"));
        //男人
        rabbitTemplate.convertAndSend
                (MqTopic.Exchange_Name,"boy.ua.dancing",getMsg("男","英国","跳舞"));
    }



    public String getMsg(String 性别,String 国籍,String 爱好){
        String msg = "性别:{a},国籍:{b},爱好:{c}";
        return msg.replace("{a}",性别)
                .replace("{b}",国籍)
                .replace("{c}",爱好);
    }
}

查看打印结果

github:https://github.com/843679400/SpringAMQP.git

本文地址:https://blog.csdn.net/li843679400/article/details/112004823

《springAMQP-模糊匹配(topic)模式.doc》

下载本文的Word格式文档,以方便收藏与打印。