RabbitMq学习(二)DirectExchange在springboot的用法

依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.xquant</groupId>
	<artifactId>xquant-rabbitmq-send</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>xquant-rabbitmq-send</name>
	<description>xquant-rabbitmq-send</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.0.5.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-amqp</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-configuration-processor</artifactId>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>


</project>

配置

在这个配置中,分以下几步:
第一步:构建交换机DirectExchange
第二步:构建队列Queue,这里我定义了两个:test1,test2
第三步:绑定交换机和队列,这里我用direct_key1这个bingdingKey来绑定DirectExchange和test1,用direct_key2这个bingdingKey来绑定DirectExchange和test2
类似于下图:
在这里插入图片描述
第四步:构建ConnectionFactory,配置链接和用户名密码,实例化RabbitTemplate
代码如下:

package com.xquant.rabbitmq.send.mq;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
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月14日 下午1:29:21
 *
 */
@Configuration
public class DirectMqConfig {

	/**
	 * 交换机名称
	 */
	public static final String DIRECT_EXCHANGE_NAME = "direct_exchange";

	/**
	 * 绑定key,交换机绑定队列时需要指定
	 */
	public static final String BINGDING_KEY_TEST1 = "direct_key1";
	public static final String BINGDING_KEY_TEST2 = "direct_key2";

	/**
	 * 队列名称
	 */
	public static final String QUEUE_TEST1 = "test1";
	public static final String QUEUE_TEST2 = "test2";

	/**
	 * 构建DirectExchange交换机
	 * 
	 * @return
	 */
	@Bean
	public DirectExchange directExchange() {
		// 支持持久化,长期不用补删除
		return new DirectExchange(DIRECT_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);
	}

	/**
	 * 绑定交交换机和
	 * 
	 * @return
	 */
	@Bean
	public Binding test1Binding() {
		return BindingBuilder.bind(test1Queue()).to(directExchange()).with(BINGDING_KEY_TEST1);
	}

	@Bean
	public Binding test2Binding() {
		return BindingBuilder.bind(test2Queue()).to(directExchange()).with(BINGDING_KEY_TEST2);
	}

	/**
	 * 配置
	 * 
	 * @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);
	}

}

生产者

为了方便测试,写一个接口,可以看出在发送消息时需要指定交换机和路由key。
第一个接口发送给队列test1
第二个接口发送给队列test2

package com.xquant.rabbitmq.send.mq;

import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author chunhui.tan
 * @version 创建时间:2018年11月14日 下午4:17:31
 *
 */
@RestController
public class ProducerController {

	@Autowired
	private RabbitTemplate rabbitTemplate;

	/**
	 * 给test1队列发消息
	 * 
	 * @return
	 */
	@GetMapping("/sendMessage1")
	public Object sendMessage1() {
		MessageProperties messageProperties = new MessageProperties();
		messageProperties.setContentEncoding("UTF-8");
		Message message = new Message("你好,这是发给test1队列的消息".getBytes(), messageProperties);
		rabbitTemplate.send(DirectMqConfig.DIRECT_EXCHANGE_NAME, DirectMqConfig.BINGDING_KEY_TEST1, message);
		return "ok";
	}

	/**
	 * 给test2队列发消息
	 * 
	 * @return
	 */
	@GetMapping("/sendMessage2")
	public Object sendMessage2() {
		MessageProperties messageProperties = new MessageProperties();
		messageProperties.setContentEncoding("UTF-8");
		Message message = new Message("你好,这是发给test2队列的消息".getBytes(), messageProperties);
		rabbitTemplate.send(DirectMqConfig.DIRECT_EXCHANGE_NAME, DirectMqConfig.BINGDING_KEY_TEST2, message);
		return "ok";
	}

}

消费者

package com.xquant.rabbitmq.send.mq;

import java.io.UnsupportedEncodingException;

import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

/**
 * @author chunhui.tan
 * @version 创建时间:2018年11月14日 下午4:21:24
 *
 */
@Component
public class Consumer {

	/**
	 * 监听test1队列
	 * 
	 * @param message
	 * @throws UnsupportedEncodingException
	 */
	@RabbitListener(queues = DirectMqConfig.QUEUE_TEST1)
	public void consumeMessage1(Message message) throws UnsupportedEncodingException {
		System.out.println("这是监听test1得到的消息:======" + new String(message.getBody(), "utf-8"));
	}

	/**
	 * 监听test2队列
	 * 
	 * @param message
	 * @throws UnsupportedEncodingException
	 */
	@RabbitListener(queues = DirectMqConfig.QUEUE_TEST2)
	public void consumeMessage2(Message message) throws UnsupportedEncodingException {
		System.out.println("这是监听test1得到的消息:======" + new String(message.getBody(), "utf-8"));
	}

}

启动项目测试

观察rabbitmq页面
在这里插入图片描述
然后点进去
在这里插入图片描述
可以看到这个交换机与队列绑定的情况,包含队列名称和对应的路由key
在这里插入图片描述
可以看到有两个队列
接着我们依次访问接口
http://localhost:8080/sendMessage1
http://localhost:8080/sendMessage2
查看控制台
在这里插入图片描述

多个绑定情况

以上演示的是一个bindingKey绑定一个队列的情况,其实我们可以用一个bindingKey绑定多个队列。
配置代码如下:

package com.xquant.rabbitmq.send.mq;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
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月14日 下午1:29:21
 *
 */
@Configuration
public class DirectMqConfig {

	/**
	 * 交换机名称
	 */
	public static final String DIRECT_EXCHANGE_NAME = "direct_exchange";

	/**
	 * 绑定key,交换机绑定队列时需要指定
	 */
	public static final String BINGDING_KEY_TEST1 = "direct_key1";
	public static final String BINGDING_KEY_TEST2 = "direct_key2";

	/**
	 * 队列名称
	 */
	public static final String QUEUE_TEST1 = "test1";
	public static final String QUEUE_TEST2 = "test2";

	/**
	 * 构建DirectExchange交换机
	 * 
	 * @return
	 */
	@Bean
	public DirectExchange directExchange() {
		// 支持持久化,长期不用补删除
		return new DirectExchange(DIRECT_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);
	}

	/**
	 * 绑定交交换机和
	 * 
	 * @return
	 */
	@Bean
	public Binding test1Binding() {
		return BindingBuilder.bind(test1Queue()).to(directExchange()).with(BINGDING_KEY_TEST1);
	}
	/**
	 * 修改这里,将绑定的key变成BINGDING_KEY_TEST1,使两个队列通过同一个bindingkey绑定到交换机
	 * 
	 * @return
	 */
	@Bean
	public Binding test2Binding() {
		return BindingBuilder.bind(test2Queue()).to(directExchange()).with(BINGDING_KEY_TEST1);
	}

	/**
	 * 配置
	 * 
	 * @return
	 */
	@Bean
	public ConnectionFactory connectionFactory() {
		CachingConnectionFactory connectionFactory = new CachingConnectionFactory("47.110.34.160", 5672);
		connectionFactory.setUsername("admin");
		connectionFactory.setPassword("123456");
		return connectionFactory;
	}

	/**
	 * 实例化操作模板
	 * 
	 * @param connectionFactory
	 * @return
	 */
	@Bean
	public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
		return new RabbitTemplate(connectionFactory);
	}

}

变化很小,只是test2Binding()方法中将绑定的key变成BINGDING_KEY_TEST1,使两个队列通过同一个bindingkey绑定到交换机。
生产者接口还是不变
消费者部分代码也不变
先web页面删除交换机和队列
然后启动项目测试
查看web页面:
在这里插入图片描述
通过同一个bindingkey将两个队列绑定到同一个交换机
生产者接口中,sendMessage2()方法中是这样的:

/**
	 * 给test2队列发消息
	 * 
	 * @return
	 */
	@GetMapping("/sendMessage2")
	public Object sendMessage2() {
		MessageProperties messageProperties = new MessageProperties();
		messageProperties.setContentEncoding("UTF-8");
		Message message = new Message("你好,这是发给test2队列的消息".getBytes(), messageProperties);
		rabbitTemplate.send(DirectMqConfig.DIRECT_EXCHANGE_NAME, DirectMqConfig.BINGDING_KEY_TEST2, message);
		return "ok";
	}

显然这里在发消息时指定的路由key是direct_key2,所以这条消息应该会丢失的。
我们访问sendMessage1接口,控制台打印如下:
在这里插入图片描述
可以看到,分别监听test1和test2的监听器都监听到了通过 direct_key1这个路由key发送的消息。

访问sendMessage2接口,
在这里插入图片描述
控制台空空如也,原本通过direct_key2这个路由键发送的消息丢失了,因为没有队列通过这个路由键来绑定交换机。

总结

  • Direct-直连交换机适合那种一对一的消息传递,通过指定的bandingKey来绑定交换机和队列
  • 使用Direct类型交换机时,bandingKey和队列时多对多的关系,即一个队列可以通过多个bandingKey来绑定交换机,一个bandingKey也可以绑定多个队列到交换机,
  • 这里只演示了一个交换机绑定多个队列的情况,其实一个队列也是可以被绑定到不同的交换机的。
  • 使用Direct类型交换机时,发送消息时,必须指定交换机和routingKey,RabbitMq会通过routingKey去匹配bandingKey,然后找到相应的队列,找到就发送消息给这个队列,找到多个就分别发消息给找到的队列,若找不到,消息则丢失
  • 在配置文件中,我习惯将绑定队列和交换机的key叫做bindingKey,在生产者发送消息时,参数值填的key叫做routingKey,其实这两个东西都是为了匹配消息和队列使用的,并无实质差别。
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Spring Boot中配置RabbitMQ的步骤如下: 1. 添加RabbitMQ依赖:在`pom.xml`文件中添加以下依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency> ``` 2. 配置RabbitMQ连接信息:在`application.properties`(或`application.yml`)文件中添加以下配置: ```properties spring.rabbitmq.host=your-rabbitmq-host spring.rabbitmq.port=your-rabbitmq-port spring.rabbitmq.username=your-username spring.rabbitmq.password=your-password ``` 替换 `your-rabbitmq-host`、`your-rabbitmq-port`、`your-username` 和 `your-password` 为实际的RabbitMQ连接信息。 3. 创建消息队列和交换机:可以使用RabbitMQ的管理界面或通过代码进行创建。下面是通过代码创建的示例: ```java import org.springframework.amqp.core.*; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class RabbitMQConfig { @Bean public Queue queue() { return new Queue("my-queue"); } @Bean public DirectExchange exchange() { return new DirectExchange("my-exchange"); } @Bean public Binding binding(Queue queue, DirectExchange exchange) { return BindingBuilder.bind(queue).to(exchange).with("my-routing-key"); } } ``` 这里创建了一个名为 "my-queue" 的队列和一个名为 "my-exchange" 的交换机,并将它们绑定在一起。 4. 发送和接收消息:可以使用`RabbitTemplate`来发送和接收消息。例如,下面是一个发送消息的示例: ```java import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component public class MessageProducer { @Autowired private RabbitTemplate rabbitTemplate; public void sendMessage(String message) { rabbitTemplate.convertAndSend("my-exchange", "my-routing-key", message); } } ``` 这里使用`RabbitTemplate`的`convertAndSend`方法来发送消息到指定的交换机和路由键。 这样就完成了Spring Boot与RabbitMQ的配置。你可以根据实际需求进行进一步的设置和操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值