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

aso*_*oto 4 java spring spring-integration

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

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

请记住,receive() 调用仅与 PollableChannels 相关。事实上, SubscribableChannel 接口甚至没有定义 receive() 方法。这样做的原因是当消息被发送到 SubscribableChannel 时,它将根据频道的类型直接发送给一个或多个订阅者(例如 PublishSubscribeChannel 发送给它的所有订阅者)。因此,preReceive(..) 和 postReceive(..) 拦截器方法仅在拦截器应用于 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);
}
Run Code Online (Sandbox Code Playgroud)

我想知道所有这些方法中的哪一个是我应该拦截消息的更安全的地方?由于其中一些无法执行,具体取决于 Channel 类型。例如,像 SubscribableChannel 一样,它不会执行接收,所以我假设 preReceive 和 postReceive 永远不会被调用。

基于此,我可以假设 preSend 是一个更安全的地方吗?

lub*_*nac 5

是的,preSend适用于所有频道类型(除了NullChannel!),并且对您的意图来说是最安全的。

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

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

AbstractPollableChannel使用preReceive,这是父QueueChannelRedezevousChannelPriorityChannel

所以,preReceive/ postReceive/afterReceiveCompletion不叫的DirectChannelExecutorChannelPublishSubscribeChannel