Channel Interceptors
消息架构的一个优势是可以提供公共行为,并通过非侵入式方式捕获有关通过系统传递的消息的有意义的信息。由于消息实例已发送到并从 MessageChannel 实例接收,因此这些通道提供了拦截发送和接收操作的机会。以下清单中所示的 ChannelInterceptor 策略接口提供了这些操作的各个方法:
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);
}
在实现该接口后,只需调用以下内容,即可将拦截器与频道注册:
channel.addInterceptor(someChannelInterceptor);
可以将返回 Message 实例的方法用于转换 Message,也可以返回 null 来防止进一步处理(当然,任何方法都可以抛出 RuntimeException)。此外,preReceive 方法可以返回 false 以防止接收操作继续进行。
请记住, |
Spring Integration 还提供了 Wire Tap 模式的实现。这是一个简单的拦截器,它将 Message
发送到另一个通道,而不会以其他方式更改现有流。它对于调试和监控非常有用。在 Wire Tap 中显示一个示例。
由于很少需要实现所有拦截器方法,因此该接口提供了无操作方法(返回 void 方法没有代码,返回消息的方法按原样返回消息,布尔方法返回 true)。
拦截器方法调用的顺序取决于通道的类型。如前所述,基于队列的通道是唯一最初拦截 |
从 Spring Framework 4.1 和 Spring Integration 4.1 开始,ChannelInterceptor 提供了新的方法:afterSendCompletion() 和 afterReceiveCompletion()。无论引发任何异常,它们都会在 send() 和 receive() 调用之后调用,从而允许资源清理。请注意,频道以相反的顺序调用 ChannelInterceptor 列表中的这些方法,即初始 preSend() 和 preReceive() 调用。
从版本 5.1 开始,全局频道拦截器现在适用于动态注册的频道——例如,在使用 Java DSL 时,通过使用 beanFactory.initializeBean() 或 IntegrationFlowContext 初始化的 bean。以前,在刷新应用程序上下文后创建 bean 时不应用拦截器。
此外,从版本 5.1 开始,当没有收到消息时,不再调用 ChannelInterceptor.postReceive();不再需要检查 null Message?)。以前,该方法被调用。如果您有一个依赖于先前行为的拦截器,请改为实现 afterReceiveCompleted(),因为无论是否收到消息,该方法都会被调用。
从 5.2 版开始, |