Channel Interceptors
消息架构的一个优势是可以提供公共行为,并通过非侵入式方式捕获有关通过系统传递的消息的有意义的信息。由于消息实例已发送到并从 MessageChannel 实例接收,因此这些通道提供了拦截发送和接收操作的机会。以下清单中所示的 ChannelInterceptor 策略接口提供了这些操作的各个方法:
One of the advantages of a messaging architecture is the ability to provide common behavior and capture meaningful information about the messages passing through the system in a non-invasive way.
Since the Message
instances are sent to and received from MessageChannel
instances, those channels provide an opportunity for intercepting the send and receive operations.
The ChannelInterceptor
strategy interface, shown in the following listing, provides methods for each of those operations:
public interface ChannelInterceptor {
Message<?> preSend(Message<?> message, MessageChannel channel);
void postSend(Message<?> message, MessageChannel channel, boolean sent);
void afterSendCompletion(Message<?> message, MessageChannel channel, boolean sent, Exception ex);
boolean preReceive(MessageChannel channel);
Message<?> postReceive(Message<?> message, MessageChannel channel);
void afterReceiveCompletion(Message<?> message, MessageChannel channel, Exception ex);
}
在实现该接口后,只需调用以下内容,即可将拦截器与频道注册:
After implementing the interface, registering the interceptor with a channel is just a matter of making the following call:
channel.addInterceptor(someChannelInterceptor);
可以将返回 Message 实例的方法用于转换 Message,也可以返回 null 来防止进一步处理(当然,任何方法都可以抛出 RuntimeException)。此外,preReceive 方法可以返回 false 以防止接收操作继续进行。
The methods that return a Message
instance can be used for transforming the Message
or can return 'null' to prevent further processing (of course, any of the methods can throw a RuntimeException
).
Also, the preReceive
method can return false
to prevent the receive operation from proceeding.
请记住, |
Keep in mind that |
Spring Integration 还提供了 Wire Tap 模式的实现。这是一个简单的拦截器,它将 Message
发送到另一个通道,而不会以其他方式更改现有流。它对于调试和监控非常有用。在 Wire Tap 中显示一个示例。
Spring Integration also provides an implementation of the Wire Tap pattern.
It is a simple interceptor that sends the Message
to another channel without otherwise altering the existing flow.
It can be very useful for debugging and monitoring.
An example is shown in Wire Tap.
由于很少需要实现所有拦截器方法,因此该接口提供了无操作方法(返回 void 方法没有代码,返回消息的方法按原样返回消息,布尔方法返回 true)。
Because it is rarely necessary to implement all of the interceptor methods, the interface provides no-op methods (those returning void
method have no code, the Message
-returning methods return the Message
as-is, and the boolean
method returns true
).
拦截器方法调用的顺序取决于通道的类型。如前所述,基于队列的通道是唯一最初拦截 |
The order of invocation for the interceptor methods depends on the type of channel.
As described earlier, the queue-based channels are the only ones where the |
从 Spring Framework 4.1 和 Spring Integration 4.1 开始,ChannelInterceptor 提供了新的方法:afterSendCompletion() 和 afterReceiveCompletion()。无论引发任何异常,它们都会在 send() 和 receive() 调用之后调用,从而允许资源清理。请注意,频道以相反的顺序调用 ChannelInterceptor 列表中的这些方法,即初始 preSend() 和 preReceive() 调用。
Starting with Spring Framework 4.1 and Spring Integration 4.1, the ChannelInterceptor
provides new methods: afterSendCompletion()
and afterReceiveCompletion()
.
They are invoked after send()' and 'receive()
calls, regardless of any exception that is raised, which allow for resource cleanup.
Note that the channel invokes these methods on the ChannelInterceptor
list in the reverse order of the initial preSend()
and preReceive()
calls.
从版本 5.1 开始,全局频道拦截器现在适用于动态注册的频道——例如,在使用 Java DSL 时,通过使用 beanFactory.initializeBean() 或 IntegrationFlowContext 初始化的 bean。以前,在刷新应用程序上下文后创建 bean 时不应用拦截器。
Starting with version 5.1, global channel interceptors now apply to dynamically registered channels - such as through beans that are initialized by using beanFactory.initializeBean()
or IntegrationFlowContext
when using the Java DSL.
Previously, interceptors were not applied when beans were created after the application context was refreshed.
此外,从版本 5.1 开始,当没有收到消息时,不再调用 ChannelInterceptor.postReceive();不再需要检查 null Message?)。以前,该方法被调用。如果您有一个依赖于先前行为的拦截器,请改为实现 afterReceiveCompleted(),因为无论是否收到消息,该方法都会被调用。
Also, starting with version 5.1, ChannelInterceptor.postReceive()
is no longer called when no message is received; it is no longer necessary to check for a null
Message<?>
.
Previously, the method was called.
If you have an interceptor that relies on the previous behavior, implement afterReceiveCompleted()
instead, since that method is invoked, regardless of whether a message is received or not.
从 5.2 版开始, |
Starting with version 5.2, the |