ConfirmCallback不触发的主因是未传CorrelationData参数;需配置publisher-confirm-type=correlated、调用convertAndSend时传入CorrelationData实例,并确保测试中主线程等待回调完成。

ConfirmCallback 不触发:最常见原因是没传 CorrelationData
即使 publisher-confirm-type 设为 correlated、setConfirmCallback 也注册了,ConfirmCallback 依然静默——大概率是因为调用 convertAndSend 时漏掉了 CorrelationData 参数。
- ❌ 错误写法:
rabbitTemplate.convertAndSend("ex", "rk", msg)→ 完全不进 confirm 流程 - ✅ 正确写法:
CorrelationData cd = new CorrelationData(UUID.randomUUID().toString()); rabbitTemplate.convertAndSend("ex", "rk", msg, cd) - 根本机制:
RabbitTemplate只对带CorrelationData的消息注册监听器;没它,Broker 即使发回 confirm 帧,Spring 也无从关联回调
配置项已过时:publisher-confirms 在新版本中无效
如果你的 application.yml 里还写着 spring.rabbitmq.publisher-confirms=true,这个配置在 Spring Boot 2.3+(对应 Spring AMQP 2.3+)已彻底废弃,不会生效。
- 必须改用:
spring.rabbitmq.publisher-confirm-type=correlated(或simple,但correlated才支持异步回调) - 同时确保:
spring.rabbitmq.publisher-returns=true(用于ReturnCallback) - 注意:默认值是
NONE,不显式配置就等于关闭确认机制
单元测试中回调“丢失”:主线程提前退出
在 @Test 方法里设了 setConfirmCallback,但控制台没输出、日志没打印——不是代码错,而是测试方法执行完,JVM 退出,异步回调线程被强制终止。
- 典型现象:调试模式下能触发,直接运行就“没反应”
- 临时解决(仅测试):
Thread.sleep(2000)或CountDownLatch.await(2, TimeUnit.SECONDS)等待回调完成 - 生产环境不用等:因为应用长期运行,回调自然能被接收;但测试必须显式保活
Bean 被覆盖或作用域错误导致回调失效
自定义了 @Bean RabbitTemplate,但 setConfirmCallback 在某个地方被重置或没生效——尤其当 RabbitTemplate 是 prototype 作用域,或被多个配置类重复初始化时。
- 检查是否加了
@Primary和@Bean,确保 Spring 使用的是你手动配置的那个实例 - 避免在非
@PostConstruct或非 Bean 初始化阶段动态设置回调(比如在 Controller 里每次 new 一个 template 再 set) - 如果用了 AOP 或代理,确认回调设置发生在代理对象创建之后(否则代理可能拦截并丢弃设置)
CorrelationData,其他都白搭。

















