我们来编写消息的生产者,Provider,回到我们的代码当中,Provider配置文件已经配置好了,在这里Receiver就不要了,
只要Sender就可以了,然后我们来看一下Sender的代码,这是我们之前写的案例,那么在这里我们需要注意的是什么呢,
现在我们需要注入两个配置文件里面的内容了,看配置文件
mq.config.exchange=log.direct
mq.config.queue.info.routing.key=log.info.routing.key
mq.config.queue.error.routing.key=log.error.routing.key
mq.config.queue.error=log.error
在这里是不是有一个交换器的名称,Provider生产者他在发送消息的时候,是不是得知道像哪个交换器发送消息,所以他在
这里也需要知道交换器的名称,那么我们也需要把它给注入进来
// exchange 交换器名称
@Value("${mq.config.exchange}")
private String exchange;
然后还要告诉他是按照哪个路径key去发送,所以路由key也要,这里我们先给一个info,
// routingkey 路由键
@Value("${mq.config.queue.error.routing.key}")
private String routingkey;
我们加一个注释,那么为什么发送消息要用到这两个值呢,我们去调用rabbitAmqpTemplate下的convertAndSend方法,来做
消息发送,实质在template下,在convertAndSend方法当中呢,它是一个重载的方法,他在这里还需要三个参数的,那么需要
三个参数的convertAndSend,那么三个参数表示什么意思呢,这个时候参数一不再是队列名称了,而是我们的交换器名称,第二个
参数是什么呢,第二个参数是路由键,参数三是什么呢,是我们的消息,这样生产者和消费者,会根据我们的名称,路由键,将消息
发送到我们的RabbitMQ当中,就跟着交换器以及路由规则,发送到RabbitMQ当中,RabbitMQ根据你发送过来的消息,他的交换器,
跟你传过来的路由键,就会将消息放到不同的队列当中,就从队列里去消息,这个能理解吧,那么我们来把这几个参数给定,
this.exchange就是交换器的名称,第二个是this.routerKey,就是路由键,第三个是消息msg,这样我们一个发送者的代码就写完了,
其实对于发送方来讲,比较简单,主要知道交换器的名称,和路由键就可以,那么接下来我们去测试一下
@Component
public class Sender {
@Autowired
private AmqpTemplate rabbitAmqpTemplate;
//exchange 交换器名称
@Value("${mq.config.exchange}")
private String exchange;
//routingkey 路由键
@Value("${mq.config.queue.error.routing.key}")
private String routingkey;
/*
* 发送消息的方法
*/
public void send(String msg){
//向消息队列发送消息
//参数一:交换器名称。
//参数二:路由键
//参数三:消息
this.rabbitAmqpTemplate.convertAndSend(this.exchange, this.routingkey, msg);
}
}
测试代码基本我们不用动什么,这里我们看一下,我们现在给的路由键是不是info,那么也就意味着消息就发送到这个队列当中,
那么对于INFO处理日志的这个,是不是能够从这里读到信息,他是不是能够读到信息,他会打印info...receiver内容,是代表我们的
代码编写是没有问题的,我们来测试一下,首先我们把消费者启动,然后再去运行发送消息的代码,观察控制台,看到了吗,现在由于我们的
给的路由key,给的是info.routing.key,所以现在产生的是info的消息,我们把生产者先停掉,我们把sender再改一个,我们把路
由键改成error,我们在配置文件里,error的路由键拿过来
mq.config.queue.error.routing.key=log.error.routing.key
放到这里我们来测试一下,回到我们的Sender当中,他就能从key里取出值了,这里给的就是error级别的路由键,我们现在再来运行,
消费者已经启动了,我们再来测试,现在我再运行,因为我们给的路由key就是error的,那么现在我们消费者这一块,他的ErrorReceiver
是不是能够执行,打印Error....Receiver,我们来看看是不是这样的,观察控制台,我们可以看到,现在是不是输出Error队列的一个消息,
所以我们这个案例当中呢,就是通过交换器,注意看匹配模式,用的是direct,发布订阅的方式,这一类交换器,不同的消息进入到不同的
队列当中,然后不同的消费者,从不同的队列里取消息的案例,这个案例主要是Direct交换器的讲解,关键在哪呢,一个是你发送消息时,
我要指定的交换器的名称,那么交换器的名称你还要保证,消费者里面,他的名称是相同的,第二个就是配置消息消费者这一块,
@RabbitListener注解里,这一块是相当重要的,关键是在这,type是ExchangeTypes,我们现在把消费者的代码整理一下,
消息生产者的代码有所改动,我们加到这里,加了一个Error的路由器,然后下面代码,主要是Sender这一块,
就是我们发送消息的方法有变化,调用convertAndSend需要三个参数的方法,以上对于direct交换器的讲解呢,
就已经结束了,下面我们再来讲其他的交换器
<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.learn</groupId>
<artifactId>rabbitmq-direct-provider</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.12.RELEASE</version>
<relativePath/>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<thymeleaf.version>3.0.9.RELEASE</thymeleaf.version>
<thymeleaf-layout-dialect.version>2.2.2</thymeleaf-layout-dialect.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-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<!-- 这个插件,可以将应用打包成一个可执行的jar包 -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
spring.application.name=rabbitmq-direct-provider
spring.rabbitmq.host=59.110.158.145
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
mq.config.exchange=log.direct
mq.config.queue.info.routing.key=log.info.routing.key
mq.config.queue.error.routing.key=log.error.routing.key
mq.config.queue.error=log.error
package com.learn;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
* 消息发送者
* @author Administrator
*
*/
@Component
public class Sender {
@Autowired
private AmqpTemplate rabbitAmqpTemplate;
//exchange 交换器名称
@Value("${mq.config.exchange}")
private String exchange;
//routingkey 路由键
@Value("${mq.config.queue.error.routing.key}")
private String routingkey;
/*
* 发送消息的方法
*/
public void send(String msg){
//向消息队列发送消息
//参数一:交换器名称。
//参数二:路由键
//参数三:消息
this.rabbitAmqpTemplate.convertAndSend(this.exchange, this.routingkey, msg);
}
}
package com.learn;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class RabbitDirectProviderApplication {
public static void main(String[] args) {
SpringApplication.run(RabbitDirectProviderApplication.class, args);
}
}
package com.learn.test;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import com.learn.RabbitDirectProviderApplication;
import com.learn.Sender;
/**
* 消息队列测试类
* @author Administrator
*
*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes=RabbitDirectProviderApplication.class)
public class QueueTest {
@Autowired
private Sender sender;
/*
* 测试消息队列
*/
@Test
public void test1()throws Exception{
while(true){
Thread.sleep(1000);
this.sender.send("Hello RabbitMQ");
}
}
}