创建生产者工程
配置pom.xml文件
<?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.cdq</groupId>
<artifactId>rabbitmq-producer-spring</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-rabbit</artifactId>
<version>2.1.8.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.1.7.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
配置文件 rabbitmq.properties
在resource 文件夹下面添加
rabbitmq.host=localhost //连接路径
rabbitmq.port=5672 //连接地址
rabbitmq.username=guest //网址登录名
rabbitmq.password=guest //网址登录密码
rabbitmq.virtual-host=/ //网址连接符号
rabbitmq.host=localhost
rabbitmq.port=5672
rabbitmq.username=guest
rabbitmq.password=guest
rabbitmq.virtual-host=/
配置文件 spring-rabbitmq-producer.xml
在resource 文件夹下面添加
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:rabbit="http://www.springframework.org/schema/rabbit"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/rabbit
http://www.springframework.org/schema/rabbit/spring-rabbit.xsd">
<!--加载配置文件-->
<!--定义rabbitmq connectionFactory (工厂模式)
确认模式开启:publisher-confirms="true"-->
<!--定义交换机队列-->
<!--定义rabbitTemplate对象操作可以在代码中方便发送消息-->
<!--消息可靠性投递(生产端)-->
<!--加载配置文件-->
<context:property-placeholder location="classpath:rabbitmq.properties"></context:property-placeholder>
<!--定义rabbitmq connectionFactory (工厂模式)
确认模式开启:publisher-confirms="true"-->
<rabbit:connection-factory id="connectionFactory" host="${rabbitmq.host}"
port="${rabbitmq.port}"
username="${rabbitmq.username}"
password="${rabbitmq.password}"
virtual-host="${rabbitmq.virtual-host}"
publisher-confirms="true"
publisher-returns="true"
/>
<!--定义交换机队列-->
<rabbit:admin connection-factory="connectionFactory"/>
<!--定义rabbitTemplate对象操作可以在代码中方便发送消息-->
<rabbit:template id="rabbitTemplate" connection-factory="connectionFactory"/>
<!--消息可靠性投递(生产端)-->
<rabbit:queue id="test_queue_confirm" name="test_queue_confirm"></rabbit:queue>
<rabbit:direct-exchange name="test_exchange_confirm">
<rabbit:bindings>
<rabbit:binding queue="test_queue_confirm" key="confirm"></rabbit:binding>
</rabbit:bindings>
</rabbit:direct-exchange>
</beans>
创建测试类 , 添加确认模式
@RunWith(SpringJUnit4ClassRunner.class) 开启Test方法
@ContextConfiguration 是引用配置文件或者配置类的注解@ContextConfiguration
这个注解通常与@RunWith(SpringJUnit4ClassRunner.class)
联合使用用来测试
@ContextConfiguration使用方式
- classpath:只会到你的class路径中查找找文件。
- classpath*:不仅包含class路径,还包括jar文件中(class路径)进行查找。
```yaml package com.cdq;
import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.amqp.rabbit.connection.CorrelationData; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.junit4.SpringRunner;
/**
- @program: one
- @description:
- @author: cdq
@create: 2021-03-29 09:31 / @RunWith (SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = “classpath:spring-rabbitmq-producer.xml”) public class ProducerTest { @Autowired private RabbitTemplate rabbitTemplate; /
- 确认模式:
- 步骤:
- 确认模式开启:ConnectionFactory中开启publisher-confirms=”true”
在rabbitTemplate定义ConfirmCallBack回调函数 */ @Test public void testConfirm() { //2. 定义回调 rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
@Override public void confirm(CorrelationData correlationData, boolean ack, String cause) {
if (ack){
//接收成功
System.out.println("接收成功消息" + cause);
}else {
//接收失败
System.out.println("接收失败消息" + cause);
//做一些处理,让消息再次发送。
}
} });
/*
- 发送消息
- 第一个参数:交换机名字
- 第二个参数:路由规则
- 第三个参数:表示消息体
- */ rabbitTemplate.convertAndSend(“test_exchange_confirm000”, “confirm”, “message confirm….”); }
}
<a name="RK68m"></a>
## 运行结果
<a name="nV2eL"></a>
### 接收失败消息
channel error; protocol method: #method<channel.close>(reply-code=404, reply-text=NOT_FOUND - no exchange 'test_exchange_confirm000' in vhost '/', class-id=60, method-id=40)<br />Disconnected from the target VM, address: '127.0.0.1:5380', transport: 'socket'<br />这时由于:_发送消息队列名字和xml中的名字对应不上_<br />test_exchange_confirm000 改变 test_exchange_confirm<br />![9.png](https://cdn.nlark.com/yuque/0/2021/png/12916683/1616983112695-b52885b4-5bfa-4f6c-bff7-26b6107b4b0b.png#align=left&display=inline&height=424&margin=%5Bobject%20Object%5D&name=9.png&originHeight=424&originWidth=1532&size=34214&status=done&style=none&width=1532)
<a name="6lh9v"></a>
### 修改后
![10.png](https://cdn.nlark.com/yuque/0/2021/png/12916683/1616983212409-9a0ac36d-1e33-4718-9eb3-f142f40f5c20.png#align=left&display=inline&height=380&margin=%5Bobject%20Object%5D&name=10.png&originHeight=380&originWidth=997&size=27439&status=done&style=none&width=997)
<a name="HvYWs"></a>
### 访问http://[http://localhost:15672](http://localhost:15672/)
![11.png](https://cdn.nlark.com/yuque/0/2021/png/12916683/1616983869966-ab085b69-a0ab-46a7-a3b4-4491bafc2296.png#align=left&display=inline&height=554&margin=%5Bobject%20Object%5D&name=11.png&originHeight=554&originWidth=1010&size=34138&status=done&style=none&width=1010)
<a name="Dm0Tq"></a>
### 接收到的消息
![12.png](https://cdn.nlark.com/yuque/0/2021/png/12916683/1616983900670-712b88a0-c8cc-4806-9272-f75db53ebcac.png#align=left&display=inline&height=509&margin=%5Bobject%20Object%5D&name=12.png&originHeight=509&originWidth=684&size=18133&status=done&style=none&width=684)
<a name="ScE6U"></a>
## 添加回退
在ProducerTest中添加
```yaml
/**
* 回退模式: 当消息发送给Exchange后,Exchange路由到Queue失败是 才会执行 ReturnCallBack
* 步骤:
* 1. 开启回退模式:publisher-returns="true"
* 2. 设置ReturnCallBack
* 3. 设置Exchange处理消息的模式:
* 1. 如果消息没有路由到Queue,则丢弃消息(默认)
* 2. 如果消息没有路由到Queue,返回给消息发送方ReturnCallBack
*/
@Test
public void testReturn() {
//交换机设置强制处理失败消息的模式
rabbitTemplate.setMandatory(true);
//2.设置ReturnCallBack
rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() {
/**
*
* @param message 消息对象
* @param replyCode 错误码
* @param replyText 错误信息
* @param exchange 交换机
* @param routingKey 路由键
*/
@Override
public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
System.out.println("return 执行了....");
System.out.println(message);
System.out.println(replyCode);
System.out.println(replyText);
System.out.println(exchange);
System.out.println(routingKey);
//处理
}
});
/*
* 发送消息
* 第一个参数:交换机名字
* 第二个参数:路由规则
* 第三个参数:表示消息体
*
* */
rabbitTemplate.convertAndSend("test_exchange_confirm", "confirm", "message confirm....");
}