RabbitMq 理论基础(三)主题交换机及java代码

rabbitmq基础(3)主题交换机 java代码

回顾一下主题交换机概念

Topic Exchange
主题交换机,这个交换机其实跟直连交换机流程差不多,但是它的特点就是在它的路由键和绑定键之间是有规则的。

简单地介绍下规则:
*(星号) 用来表示一个单词 (必须出现的)
#(井号) 用来表示任意数量(零个或多个)单词
通配的绑定键是跟队列进行绑定的,举个小例子
队列Q1 绑定键为 .TT. 队列Q2绑定键为 TT.#
如果一条消息携带的路由键为 A.TT.B,那么队列Q1将会收到;
如果一条消息携带的路由键为TT.AA.BB,那么队列Q2将会收到;

主题交换机是非常强大的,为啥这么膨胀?
当一个队列的绑定键为 “#”(井号) 的时候,这个队列将会无视消息的路由键,接收所有的消息。当 * (星号) 和 # (井号) 这两个特殊字符都未在绑定键中出现的时候,此时主题交换机就拥有的直连交换机的行为。
所以主题交换机也就实现了扇形交换机的功能,和直连交换机的功能。

上代码:

(1)主题交换机配置类

package com.zyw.rabbitmq.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;

/**
 * @author  zyw
 * 主题交换机
 * 主题交换机,这个交换机其实跟直连交换机流程差不多,
 * 但是它的特点就是在它的路由键和绑定键之间是有规则的。
 */
@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,才会分发到该队列
     * @return
     */
    @Bean
    Binding bindingExchangeMessage() {
        return BindingBuilder.bind(firstQueue()).to(exchange()).with(man);
    }
    /**
     * 将secondQueue和topicExchange绑定,而且绑定的键值为用上通配路由键规则topic.#
     * 这样只要是消息携带的路由键是以topic.开头,都会分发到该队列
     * 适用场景:消息需要基于多重条件进行路由到达对应队列,
     * 例如:日志系统,不仅可以根据日志的级别而且能根据日志的来源进行订阅。
     * @return
     */
    @Bean
    Binding bindingExchangeMessage2() {
        return BindingBuilder.bind(secondQueue()).to(exchange()).with("topic.#");
    }
}

(2)主题交换机生成者

package com.zyw.rabbitmq.controller;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

/**
 * @author zyw
 * 主题交换机
 */
@EnableScheduling
@Configuration
public class TopicController {

    @Autowired
    RabbitTemplate rabbitTemplate;

    @Scheduled(cron = "0 */1 * * * ?")
    public void sendTopicMessage(){ // 主题交换机
        System.out.println("---------主题交换机開始----------------------");
        Map<String,Object> map = new HashMap<>();
        map.put("id","1111");
        map.put("name","zyw");
        //交换机---路由键--值
        rabbitTemplate.convertAndSend("topicExchange", "topic.man", map);
        System.out.println("---------主题交换机結束----------------------");
    }
}

(3)消费者
下面这个可以正常接收到topic.man,和topic.*的消息

package com.zyw.rabbitcustomer;

import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * @author zyw
 */
@Component
@RabbitListener(queues = "topic.man")
public class TopicManReceiver {
    @RabbitHandler
    public void process(Map<String,Object> map){
        System.out.println("TopicManReceiver消费者收到消息  : " + map.toString());
    }
}

下面这个可以正常接收到topic.woman,和topic.*的消息

package com.zyw.rabbitcustomer;

import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * @author zyw
 */
@Component
@RabbitListener(queues = "topic.woman")
public class TopicReceiver { // 只有绑定路由键是topic.woman或者topic.* 才能监听到队列

    @RabbitHandler
    public void process(Map<String,Object> map){
        System.out.println("TopicReceiver消费者收到消息33  : " + map.toString());
    }
}

消费者返回消息

DirectReceiver消费者收到消息  : 66666
TopicManReceiver消费者收到消息  : {name=zyw, id=1111}
TopicReceiver消费者收到消息33  : {name=zyw, id=1111}

特别注意 虽然我们在生成者只绑定了topic.man这个但是实际上topic.woman这个也可正常接收到消息,应为我们在配置类中将路由topic.*已经和交换机绑定了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值