处理异常

默认情况下,如果带注释的侦听器方法引发异常,则会将其引发到容器中,并且消息将被重新排队并重新传送、丢弃或路由到死信交换,具体取决于容器和代理配置。 不会向发件人返回任何内容。spring-doc.cadn.net.cn

从版本 2.0 开始,@RabbitListenerannotation 具有两个新属性:errorHandlerreturnExceptions.spring-doc.cadn.net.cn

默认情况下,这些未配置。spring-doc.cadn.net.cn

您可以使用errorHandler要提供RabbitListenerErrorHandler实现。 该功能接口有一种方法,如下所示:spring-doc.cadn.net.cn

@FunctionalInterface
public interface RabbitListenerErrorHandler {

    Object handleError(Message amqpMessage, org.springframework.messaging.Message<?> message,
              ListenerExecutionFailedException exception) throws Exception;

}

如您所见,您可以访问从容器接收的原始消息 spring-messagingMessage<?>对象,以及侦听器抛出的异常(包装在ListenerExecutionFailedException). 错误处理程序可以返回一些结果(作为回复发送)或引发原始异常或新异常(引发到容器或返回给发送者,具体取决于returnExceptions设置)。spring-doc.cadn.net.cn

returnExceptions属性,当true,将导致异常返回给发件人。 异常包装在RemoteInvocationResult对象。 在发送方,有一个可用的RemoteInvocationAwareMessageConverterAdapter,如果将其配置为RabbitTemplate重新引发服务器端异常,包装在AmqpRemoteException. 服务器异常的堆栈跟踪是通过合并服务器和客户端堆栈跟踪来合成的。spring-doc.cadn.net.cn

此机制通常仅适用于默认的SimpleMessageConverter,它使用 Java 序列化。 异常通常不是“Jackson 友好”的,并且不能序列化为 JSON。 如果您使用 JSON,请考虑使用errorHandler返回一些其他对 Jackson 友好的Errorobject 的 intent 值。
在版本 2.1 中,此接口从 packageo.s.amqp.rabbit.listenero.s.amqp.rabbit.listener.api.

从版本 2.1.7 开始,Channel在消息报头中可用;这允许你在使用AcknowledgeMode.MANUAL:spring-doc.cadn.net.cn

public Object handleError(Message amqpMessage, org.springframework.messaging.Message<?> message,
          ListenerExecutionFailedException exception) {
              ...
              message.getHeaders().get(AmqpHeaders.CHANNEL, Channel.class)
                  .basicReject(message.getHeaders().get(AmqpHeaders.DELIVERY_TAG, Long.class),
                               true);
          }

从版本 2.2.18 开始,如果抛出消息转换异常,将调用错误处理程序,并使用nullmessage论点。 这允许应用程序向调用者发送一些结果,指示收到了格式错误的消息。 以前,此类错误由容器引发和处理。spring-doc.cadn.net.cn