Java RabbitListener不会拾取使用AsyncRabbitTemplate发送的所有消息

Java RabbitListener不会拾取使用AsyncRabbitTemplate发送的所有消息,java,spring,asynchronous,integration-testing,spring-rabbit,Java,Spring,Asynchronous,Integration Testing,Spring Rabbit,我正在Spring Boot版本1.5.4上使用Spring Boot项目,其中包含Spring Boot starter amqp、Spring Boot starter web服务和Spring ws支持v。2.4.0. 到目前为止,我已经成功地创建了一个@RabbitListener组件,当消息通过rabbitmplate.sendAndReceive(uri,message)发送到代理时,该组件完全执行它应该执行的操作。我试图看看如果为此使用AsyncRabbitTemplate会发生什

我正在Spring Boot版本1.5.4上使用Spring Boot项目,其中包含
Spring Boot starter amqp
Spring Boot starter web服务
Spring ws支持
v。2.4.0. 到目前为止,我已经成功地创建了一个
@RabbitListener
组件,当消息通过
rabbitmplate.sendAndReceive(uri,message)
发送到代理时,该组件完全执行它应该执行的操作。我试图看看如果为此使用
AsyncRabbitTemplate
会发生什么,因为消息处理可能需要一段时间,我不想在等待响应时锁定应用程序

问题是:我放入队列的第一条消息甚至没有被侦听器拾取。回调仅使用已发布的消息而不是返回的消息确认成功

侦听器:

@RabbitListener(队列=密钥\u消息\u队列)
公共消息processMessage(@Payload byte[]Payload,@Headers映射头){
试一试{
字节[]resultBody=messageProcessor.processMessage(有效负载、标头);
MessageBuilder=MessageBuilder.withBody(resultBody);
if(resultBody.length==0){
setHeader(HEADER\u NAME\u ERROR\u消息,“处理过程中出错”);
}
返回builder.build();
}捕获(例外情况除外){
返回MessageBuilder.withBody(空正文)
.setHeader(标题\名称\错误\消息,例如getMessage())
.setHeader(标题\名称\堆栈\跟踪,例如getStackTrace())
.build();
}
}
当我执行测试时,一个测试失败,第二个测试成功。类用
@runwithing(SpringJUnit4ClassRunner.class)
@springbootstest(class={Application.class,Test.TestConfiguration.class})进行注释。
并具有
brokerruning.isrunning wintraintyqueues(QUEUE\u NAME)

测试配置(内部类):

公共静态类TestConfiguration{
@Bean//在测试中作为艺术引用
公共异步RabbitTemplate异步RabbitTemplate(ConnectionFactory ConnectionFactory,RabbitTemplate RabbitTemplate){
SimpleMessageListenerContainer容器=新的SimpleMessageListenerContainer(connectionFactory);
container.setQueueNames(队列名称);
返回新的AsyncRabbitTemplate(rabbitTemplate,容器);
}
@豆子
public MessageListener MessageListener(){
返回新的MessageListener();
}
}
测试:

@测试
public void shouldListendReplyToQueue()引发异常{
doReturn(结果/正文)
.when(innerMock)
.processMessage(any(byte[].class)、anyMapOf(String.class、Object.class));
Message msg=MessageBuilder
.withBody(消息体)
.setHeader(“标题”、“值”)
.setHeader(“身份验证”、“诱惑”)
.build();
RabbitMessageFuture pendingReply=art.SendReceive(队列名称,msg);
pendingReply.addCallback(新ListenableFutureCallback(){
@凌驾
成功时公共无效(消息结果){}
@凌驾
失效时的公共无效(可丢弃的ex){
抛出新的运行时异常(ex);
}
});
而(!pendingReply.isDone()){}
结果=pendingReply.get();
//省略断言
}
测试2:

@测试
public void shouldReturnExceptionToCaller()引发异常{
doThrow(新的SSLSenderInstantiationException(“我是一条消息”,新的异常()))
.when(innerMock)
.processMessage(any(byte[].class)、anyMapOf(String.class、Object.class));
Message msg=MessageBuilder
.withBody(消息体)
.setHeader(“标题”、“值”)
.setHeader(“身份验证”、“诱惑”)
.build();
RabbitMessageFuture pendingReply=art.SendReceive(队列名称,msg);
pendingReply.addCallback(/*同上*/);
而(!pendingReply.isDone()){}
结果=pendingReply.get();
//省略断言
}
当我同时运行这两个测试时,第一个执行的测试失败,而第二个调用成功。 当我分别运行这两个测试时,两个都会失败。 当我添加一个
@Before
-方法,该方法使用AsyncRabbitTemplate
art
将任何消息放入队列时,两个测试都可能通过,或者第二个测试可能不通过,因此除了意外之外,行为也不一致

有趣的是,传递给方法的回调在调用侦听器之前报告成功,并报告发送的消息作为结果

该类中唯一缺少的类是通用配置类,该类用
@EnableRabbit
注释,并包含以下内容:

@Bean
公共SimpleRableBitListenerContainerFactory SimpleRableBitListenerContainerFactory(ConnectionFactory ConnectionFactory){
SimpleRableBitListenerContainerFactory=新SimpleRableBitListenerContainerFactory();
工厂。设置连接工厂(连接工厂);
工厂用户(10);
返回工厂;
}
我尝试过的其他事情:

  • 专门创建
    AsyncRabbitTemplate
    我自己,在每个消息处理之前和之后手动启动和停止它->两个测试都成功
  • 增加/减少接收超时->无效
  • 删除并更改回调->无效
  • 再次显式创建队列,注入的
    RabbitAdmin
    ->无效
  • 将回调提取到一个常量->测试甚至没有正确启动
  • 如上所述,我直接使用了
    rabbitmplate
    ,这完全符合预期
如果有人知道缺少什么,我很高兴听到。

你不能
@Bean // referenced in the tests as art
public AsyncRabbitTemplate asyncRabbitTemplate(ConnectionFactory connectionFactory, RabbitTemplate rabbitTemplate) {
    SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory);
    container.setQueueNames(QUEUE_NAME);
    return new AsyncRabbitTemplate(rabbitTemplate, container);
}
RabbitMessageFuture pendingReply = art.sendAndReceive(QUEUE_NAME, msg);
RabbitMessageFuture pendingReply = art.sendAndReceive(KEY_MESSAGING_QUEUE, msg);