publisher-confirms-type=”simple“ 实现 传统spring 非springboot
时间: 2025-07-26 13:20:06 AIGC 浏览: 19
<think>我们正在处理一个关于在传统Spring框架(非Spring Boot)中实现RabbitMQ的发布确认(publisher confirms)功能,并且要求使用simple类型的问题。根据引用内容,我们知道在Spring Boot 2.2.0之后,配置项从`spring.rabbitmq.publisher-confirm`变成了`spring.rabbitmq.publisher-confirm-type`,并且simple类型有两种行为:一种是触发回调方法,另一种是允许我们使用`waitForConfirms`或`waitForConfirmsOrDie`方法等待broker的确认。
在传统Spring项目中,我们通常通过XML配置或者Java配置来设置RabbitMQ。为了实现发布确认功能,我们需要配置`CachingConnectionFactory`,并设置其`publisherConfirmType`属性为`ConfirmType.SIMPLE`。
步骤:
1. 配置连接工厂,启用发布者确认(publisher confirms)。
2. 设置发布者确认类型为SIMPLE。
3. 在发送消息后,使用`waitForConfirms`或`waitForConfirmsOrDie`来等待确认(如果需要)。
注意:在传统Spring项目中,我们通常不使用application.properties来配置,而是通过Bean定义来配置。
下面我们通过Java配置的方式来实现:
首先,我们需要配置RabbitMQ连接工厂,设置发布者确认模式为SIMPLE。
```java
@Configuration
public class RabbitConfig {
@Bean
public CachingConnectionFactory rabbitConnectionFactory() {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory("localhost");
connectionFactory.setUsername("guest");
connectionFactory.setPassword("guest");
connectionFactory.setVirtualHost("/");
// 设置发布者确认模式,这里我们使用SIMPLE
connectionFactory.setPublisherConfirmType(CachingConnectionFactory.ConfirmType.SIMPLE);
// 注意:如果要使用SIMPLE的第二种行为(即使用waitForConfirms),还需要设置publisherReturns为true(如果需要处理返回消息的话)
connectionFactory.setPublisherReturns(true);
return connectionFactory;
}
// 其他必要的Bean,如RabbitTemplate等
@Bean
public RabbitTemplate rabbitTemplate(CachingConnectionFactory rabbitConnectionFactory) {
RabbitTemplate template = new RabbitTemplate(rabbitConnectionFactory);
// 设置mandatory为true,这样如果消息无法路由到队列,会触发returnedMessage回调
template.setMandatory(true);
// 设置确认回调(如果需要处理确认)和返回回调(如果需要处理返回)
template.setConfirmCallback((correlationData, ack, cause) -> {
if (!ack) {
System.out.println("Message send failed: " + cause);
}
});
template.setReturnCallback((message, replyCode, replyText, exchange, routingKey) -> {
System.out.println("Returned message: " + new String(message.getBody()));
});
return template;
}
}
```
但是,请注意,上面的配置中,我们设置了`ConfirmCallback`,这在SIMPLE模式下也会被触发(即第一种行为)。如果我们想要使用第二种行为,即调用`waitForConfirms`方法,那么我们需要在发送消息后手动调用这些方法。但是,RabbitTemplate本身并不直接提供这样的方法。因此,我们需要通过其他方式来实现。
实际上,在SIMPLE模式下,第二种行为需要我们从连接工厂获取一个Channel,然后使用这个Channel发送消息,并调用`waitForConfirms`方法。但是,这通常不是使用RabbitTemplate的方式,因为RabbitTemplate封装了这些底层操作。
如果我们确实需要使用`waitForConfirms`方法,我们可以使用`RabbitTemplate`的`execute`方法,在Channel上执行操作:
```java
rabbitTemplate.execute(channel -> {
// 使用channel发送消息
channel.basicPublish(exchange, routingKey, properties, body);
// 等待确认
if (!channel.waitForConfirms(1000)) { // 等待1秒
// 消息未确认,处理失败
}
return null;
});
```
但是,这种方法需要我们手动发送消息,而绕过了RabbitTemplate的很多特性(如转换器、回调等)。因此,我们通常不建议这样做。
在大多数情况下,我们更倾向于使用RabbitTemplate的确认回调(ConfirmCallback)来处理发布确认,即使是在SIMPLE模式下,它也会被触发。因此,我们可以像上面配置RabbitTemplate那样设置ConfirmCallback,然后通过回调来处理确认结果。
总结:
1. 配置CachingConnectionFactory,设置publisherConfirmType为ConfirmType.SIMPLE。
2. 配置RabbitTemplate,设置ConfirmCallback来处理确认结果(异步方式)。
3. 如果确实需要同步等待确认(使用waitForConfirms),则可以使用RabbitTemplate的execute方法,在Channel上手动发送消息并等待确认,但这通常不是推荐的做法。
因此,在传统Spring项目中,我们通常采用异步回调的方式处理发布确认。
相关问题:
1. 在传统Spring项目中,如何配置RabbitMQ的消息返回(Returns)机制?
2. RabbitMQ的发布确认(publisher confirms)和消息返回(Returns)有什么区别?
3. 除了SIMPLE类型,RabbitMQ的发布确认还有哪些类型?它们分别适用于什么场景?</think>在传统 Spring 框架中实现 RabbitMQ 的发布确认(publisher confirms)功能(使用 SIMPLE 类型),需通过以下步骤配置:
### 配置步骤
1. **配置连接工厂**
```xml
<bean id="connectionFactory" class="org.springframework.amqp.rabbit.connection.CachingConnectionFactory">
<property name="host" value="your.rabbitmq.host"/>
<property name="publisherConfirmType" value="SIMPLE"/> <!-- 关键配置 -->
<property name="publisherReturns" value="true"/> <!-- 启用返回机制 -->
</bean>
```
2. **配置 RabbitTemplate**
```xml
<bean id="rabbitTemplate" class="org.springframework.amqp.rabbit.core.RabbitTemplate">
<property name="connectionFactory" ref="connectionFactory"/>
<property name="mandatory" value="true"/> <!-- 启用强制路由失败返回 -->
<property name="confirmCallback" ref="confirmCallback"/> <!-- 确认回调 -->
<property name="returnCallback" ref="returnCallback"/> <!-- 路由失败回调 -->
</bean>
```
3. **实现回调接口**
```java
public class RabbitConfirmCallback implements RabbitTemplate.ConfirmCallback, RabbitTemplate.ReturnCallback {
@Override
public void confirm(CorrelationData correlationData, boolean ack, String cause) {
if (ack) {
System.out.println("消息到达交换机: " + correlationData.getId());
} else {
System.out.println("消息未到达交换机: " + cause);
}
}
@Override
public void returnedMessage(Message message, int replyCode, String replyText,
String exchange, String routingKey) {
System.out.println("消息路由失败: " + new String(message.getBody()));
}
}
```
### 使用 waitForConfirms(SIMPLE 特有)
在 SIMPLE 模式下,可同步等待确认结果:
```java
rabbitTemplate.invoke(actions -> {
actions.send(exchange, routingKey, message);
// 同步等待确认(最多等待 5 秒)
boolean confirmed = actions.getChannel().waitForConfirms(5000);
if (!confirmed) {
throw new RuntimeException("消息未确认");
}
return null;
});
```
### 关键说明
1. **SIMPLE 模式特性**:
- 触发 `ConfirmCallback` 回调(消息到达交换机时)
- 支持同步调用 `waitForConfirms()` 等待确认
- 若 `waitForConfirmsOrDie()` 返回 `false` 会关闭 `Channel`[^3]
2. **注意事项**:
- 需同时启用 `publisherReturns=true` 和 `mandatory=true` 处理路由失败
- 同步等待会阻塞线程,建议在异步场景使用回调机制
- 确保消息幂等性,防止重复投递
> **提示**:在传统 Spring 中需手动实现回调接口,而 Spring Boot 可通过 `application.properties` 配置 `spring.rabbitmq.publisher-confirm-type=simple`[^1][^2]。
---
阅读全文
相关推荐




















