FanoutExchange可以叫做广播模式,他在绑定队列时不需要指定bindingKey,消息生产者在发送消息时也不需要指定routingKey,任何发送到FanoutExchange的消息都会被转发到与之绑定的队列中去
总结特点如下:
- FanoutExchange模式需要提前将 Exchange 与 Queue 进行绑定,一个 Exchange 可以绑定多个 Queue,一个 Queue 可以同多个 Exchange 进行绑定。是多对多关系
- 不需要 RoutingKey。
- 如果接受到消息的 Exchange 没有与任何 Queue 绑定,则消息会被抛弃。
配置
没有指定bindingKey,直接将两个队列绑定到FanoutExchange
package com.xquant.rabbitmq.send.mq;
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.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author chunhui.tan
* @version 创建时间:2018年11月15日 下午3:29:38
*
*/
@Configuration
public class FanoutMqConfig {
/**
* 交换机名称
*/
public static final String FANOUT_EXCHANGE_NAME = "fanout_exchange";
/**
* 两个queue名字
*/
public static final String QUEUE_TEST1 = "fanout_queue1";
public static final String QUEUE_TEST2 = "fanout_queue2";
/**
* 构建topic类型交换机
*
* @return
*/
@Bean
public FanoutExchange fanoutExchange() {
return new FanoutExchange(FANOUT_EXCHANGE_NAME, true, false);
}
/**
* 构建序列
*
* @return
*/
@Bean
public Queue test1Queue() {
// 支持持久化
return new Queue(QUEUE_TEST1, true);
}
@Bean
public Queue test2Queue() {
// 支持持久化
return new Queue(QUEUE_TEST2, true);
}
/**
* 绑定关系
*/
@Bean
public Binding test1Binding() {
return BindingBuilder.bind(test1Queue()).to(fanoutExchange());
}
@Bean
public Binding test2Binding() {
return BindingBuilder.bind(test2Queue()).to(fanoutExchange());
}
/**
* 配置
*
* @return
*/
@Bean
public ConnectionFactory connectionFactory() {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory("127.0.0.1", 5672);
connectionFactory.setUsername("admin");
connectionFactory.setPassword("123456");
return connectionFactory;
}
/**
* 实例化操作模板
*
* @param connectionFactory
* @return
*/
@Bean
public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
return new RabbitTemplate(connectionFactory);
}
}
生产者
为了方便测试,依旧写在接口里面,直接给FanoutExchange交换机发消息,不需要指定routingKey。
@GetMapping("/sendMessage1")
public Object sendMessage1() {
MessageProperties messageProperties = new MessageProperties();
messageProperties.setContentEncoding("UTF-8");
Message message = new Message("随便发条消息,谁会收到这条消息呢,".getBytes(), messageProperties);
rabbitTemplate.send(FanoutMqConfig.FANOUT_EXCHANGE_NAME, "", message);
return "ok";
}
消费者
/**
* 监听test1队列
*
* @param message
* @throws UnsupportedEncodingException
*/
@RabbitListener(queues = FanoutMqConfig.QUEUE_TEST1)
public void consumeMessage1(Message message) throws UnsupportedEncodingException {
System.out.println("这是监听QUEUE_TEST1得到的消息:======" + new String(message.getBody(), "utf-8"));
}
/**
* 监听test1队列
*
* @param message
* @throws UnsupportedEncodingException
*/
@RabbitListener(queues = FanoutMqConfig.QUEUE_TEST2)
public void consumeMessage2(Message message) throws UnsupportedEncodingException {
System.out.println("这是监听QUEUE_TEST2得到的消息:======" + new String(message.getBody(), "utf-8"));
}
测试
启动项目,观察rabbitMq的web页面
访问http://localhost:8080/sendMessage1,控制台打印如下
消费者消费消息成功。