Handling Message Advice
如 the introduction to this section 中所讨论的,请求处理程序通知链中的通知对象仅应用于当前端点,而不是下游流程(如果有)。对于产生回复的 MessageHandler
对象(例如扩展 AbstractReplyProducingMessageHandler
的对象),通知应用于内部方法: handleRequestMessage()
(从 MessageHandler.handleMessage()
调用)。对于其他消息处理程序,通知应用于 MessageHandler.handleMessage()
。
As discussed in the introduction to this section, advice objects in a request handler advice chain are applied to just the current endpoint, not the downstream flow (if any).
For MessageHandler
objects that produce a reply (such as those that extend AbstractReplyProducingMessageHandler
), the advice is applied to an internal method: handleRequestMessage()
(called from MessageHandler.handleMessage()
).
For other message handlers, the advice is applied to MessageHandler.handleMessage()
.
在某些情况下,即使消息处理程序是 AbstractReplyProducingMessageHandler
,也必须将通知应用于 handleMessage
方法。例如,idempotent receiver 可能会返回 null
,如果处理程序的 replyRequired
属性设置为 true
,这会导致异常。另一个示例是 BoundRabbitChannelAdvice
,请参阅 Strict Message Ordering 。
There are some circumstances where, even if a message handler is an AbstractReplyProducingMessageHandler
, the advice must be applied to the handleMessage
method.
For example, the idempotent receiver might return null
, which would cause an exception if the handler’s replyRequired
property is set to true
.
Another example is the BoundRabbitChannelAdvice
— see Strict Message Ordering.
从 4.3.1 版本开始,引入了新的 HandleMessageAdvice
接口及其基本实现 (AbstractHandleMessageAdvice
)。实现 HandleMessageAdvice
的“建议”对象始终应用于 handleMessage()
方法,无论处理程序类型如何。
Starting with version 4.3.1, a new HandleMessageAdvice
interface and its base implementation (AbstractHandleMessageAdvice
) have been introduced.
Advice
objects that implement HandleMessageAdvice
are always applied to the handleMessage()
method, regardless of the handler type.
了解当应用于返回响应的处理程序时,HandleMessageAdvice
实现(如 idempotent receiver)与 adviceChain
分离并正确应用于 MessageHandler.handleMessage()
方法非常重要。
It is important to understand that HandleMessageAdvice
implementations (such as idempotent receiver), when applied to a handlers that return responses, are dissociated from the adviceChain
and properly applied to the MessageHandler.handleMessage()
method.
由于此解关联,所以不会遵守 advice 链顺序。 |
Because of this disassociation, the advice chain order is not honored. |
考虑以下配置:
Consider the following configuration:
<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>
中调用的 before。为了保持顺序,您应该遵循标准的 Spring AOP 配置方法,并将端点 id
与 .handler
后缀一起使用以获取目标 MessageHandler
bean。请注意,在这种情况下,整个下游流程都在事务范围内。
In the preceding example, the <tx:advice>
is applied to the AbstractReplyProducingMessageHandler.handleRequestMessage()
.
However, myHandleMessageAdvice
is applied for to MessageHandler.handleMessage()
.
Therefore, it is invoked before the <tx:advice>
.
To retain the order, you should follow the standard Spring AOP configuration approach and use an endpoint id
together with the .handler
suffix to obtain the target MessageHandler
bean.
Note that, in that case, the entire downstream flow is within the transaction scope.
对于不返回响应的 MessageHandler
,将保留建议链的顺序。
In the case of a MessageHandler
that does not return a response, the advice chain order is retained.
从 5.3 版本开始,HandleMessageAdviceAdapter
被用于为 MessageHandler.handleMessage()
方法以及整个子流程应用任何 MethodInterceptor
。例如,RetryOperationsInterceptor
可以应用于从某个端点开始的整个子流程;默认情况下这是不可能的,因为使用者端点仅将建议应用于 AbstractReplyProducingMessageHandler.RequestHandler.handleRequestMessage()
。
Starting with version 5.3, the HandleMessageAdviceAdapter
is provided to apply any MethodInterceptor
for the MessageHandler.handleMessage()
method and, therefore, the whole sub-flow.
For example, a RetryOperationsInterceptor
could be applied to the whole sub-flow starting from some endpoint; this is not possible, by default, because the consumer endpoint applies advices only to the AbstractReplyProducingMessageHandler.RequestHandler.handleRequestMessage()
.