处理消息通知
正如 本节引言中所讨论的,请求处理程序通知链中的通知对象仅应用于当前端点,而不应用于下游流(如果有)。
对于生成回复的 MessageHandler 对象(例如那些扩展 AbstractReplyProducingMessageHandler 的对象),通知应用于内部方法:handleRequestMessage()(从 MessageHandler.handleMessage() 调用)。
对于其他消息处理程序,通知应用于 MessageHandler.handleMessage()。
在某些情况下,即使消息处理程序是 AbstractReplyProducingMessageHandler,通知也必须应用于 handleMessage 方法。
例如,幂等接收器可能返回 null,如果处理程序的 replyRequired 属性设置为 true,这将导致异常。
另一个例子是 BoundRabbitChannelAdvice — 请参阅 严格消息排序。
从 4.3.1 版开始,引入了新的 HandleMessageAdvice 接口及其基本实现 (AbstractHandleMessageAdvice)。
实现 HandleMessageAdvice 的 Advice 对象始终应用于 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,用于将任何 MethodInterceptor 应用于 MessageHandler.handleMessage() 方法,从而应用于整个子流。
例如,可以将 RetryOperationsInterceptor 应用于从某个端点开始的整个子流;这默认情况下是不可能的,因为消费者端点仅将通知应用于 AbstractReplyProducingMessageHandler.RequestHandler.handleRequestMessage()。