处理消息建议

本节介绍 中所述,请求处理程序建议链中的建议对象仅应用于当前端点,而不应用于下游流(如果有)。对于产生回复的 MessageHandler 对象(例如扩展 AbstractReplyProducingMessageHandler 的对象),建议应用于内部方法:handleRequestMessage()(从 MessageHandler.handleMessage() 调用)。对于其他消息处理程序,建议应用于 MessageHandler.handleMessage()

在某些情况下,即使消息处理程序是 AbstractReplyProducingMessageHandler,也必须将建议应用于 handleMessage 方法。例如,幂等接收器 可能会返回 null,如果处理程序的 replyRequired 属性设置为 true,这会导致异常。另一个例子是 BoundRabbitChannelAdvice,请参阅 严格消息排序

从版本 4.3.1 开始,引入了新的 HandleMessageAdvice 接口及其基本实现(AbstractHandleMessageAdvice)。实现 HandleMessageAdviceAdvice 对象始终应用于 handleMessage() 方法,而不管处理程序类型如何。

重要的是要理解,HandleMessageAdvice 实现(例如 幂等接收器)在应用于返回响应的处理程序时,会与 adviceChain 分离,并正确应用于 MessageHandler.handleMessage() 方法。

由于这种分离,建议链顺序不会被遵守。

考虑以下配置

<some-reply-producing-endpoint ... >
    <int:request-handler-advice-chain>
        <tx:advice ... />
        <ref bean="myHandleMessageAdvice" />
    </int:request-handler-advice-chain>
</some-reply-producing-endpoint>

在前面的示例中,<tx:advice> 应用于 AbstractReplyProducingMessageHandler.handleRequestMessage()。但是,myHandleMessageAdvice 应用于 MessageHandler.handleMessage()。因此,它在 <tx:advice> 之前被调用。为了保留顺序,您应该遵循标准的 Spring AOP 配置方法,并使用端点 id 以及 .handler 后缀来获取目标 MessageHandler bean。请注意,在这种情况下,整个下游流程都在事务范围内。

对于不返回响应的 MessageHandler,建议链顺序将被保留。

从 5.3 版本开始,提供了 HandleMessageAdviceAdapter 来为 MessageHandler.handleMessage() 方法应用任何 MethodInterceptor,因此整个子流程也是如此。例如,可以将 RetryOperationsInterceptor 应用于从某个端点开始的整个子流程;默认情况下,这是不可能的,因为消费者端点仅将建议应用于 AbstractReplyProducingMessageHandler.RequestHandler.handleRequestMessage()