适用于所有类型频道的频道拦截器

Channel Interceptor for all type of channels

我正在尝试创建一个通道拦截器,它将一些数据添加到消息的 headers 中,并可能检查 MDC(映射诊断上下文)中是否有信息,尽管第二部分是我还没有开始弄清楚。

对于第一部分,我正在阅读 spring 集成的文档并说:

Keep in mind that receive() calls are only relevant for PollableChannels. In fact the SubscribableChannel interface does not even define a receive() method. The reason for this is that when a Message is sent to a SubscribableChannel it will be sent directly to one or more subscribers depending on the type of channel (e.g. a PublishSubscribeChannel sends to all of its subscribers). Therefore, the preReceive(..) and postReceive(..) interceptor methods are only invoked when the interceptor is applied to a PollableChannel.

查看拦截器需要实现的接口:

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 类型执行。例如 SubscribableChannel,它不会执行接收,所以我假设 preReceive 和 postReceive 永远不会被调用。

基于此,我可以假设 preSend 是执行此操作的更安全的地方吗?

是的,所有频道类型(NullChannel 除外!)都会调用 preSend,这对您的意图来说是最安全的。

您可以在 Spring 集成代码中找到它:

AbstractMessageChannel 是对所有通道类型(NullChannel 除外)的抽象 class,并且正在使用 preSend.

AbstractPollableChannel 正在使用 preReceive,它是 QueueChannelRedezevousChannelPriorityChannel.

的父级

所以 preReceive/postReceive/afterReceiveCompletion 不会被调用 DirectChannel, ExecutorChannelPublishSubscribeChannel.