处理消息建议
正如本节引言所述,请求处理器通知链中的通知对象仅应用于当前端点,而非下游流(如果存在)。对于生成回复的 MessageHandler 对象(例如扩展 AbstractReplyProducingMessageHandler 的处理器),通知将应用于内部方法:handleRequestMessage()(从 MessageHandler.handleMessage() 调用)。对于其他消息处理器,通知将应用于 MessageHandler.handleMessage()。
从 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,用于为 MessageHandler.handleMessage() 方法(以及整个子流程)应用任何 MethodInterceptor。例如,可以从某个端点开始,将 RetryOperationsInterceptor 应用于整个子流程;这在默认情况下是不可能的,因为消费者端点仅将通知应用于 AbstractReplyProducingMessageHandler.RequestHandler.handleRequestMessage()。