Andrés Soto
Andrés Soto

Reputation: 1004

Channel Interceptor for all type of channels

I'm trying to create a channel interceptor that will add some data to the message's headers and possible check if there is information in the MDC (Mapped Diagnostic Context) although the second part is something that I haven't start figuring out.

For the first part, I was reading spring integration's documentation and saids:

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.

Seeing the interface that needs to be implemented for the interceptor:

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);
}

I was wondering which of all of this methods is the safer place where I should be intercepting the message? Since some of them could not be executed depending on the Channel type. Like the SubscribableChannel for example, it will not execute the receive so I assume the preReceive and postReceive will get never called.

Based on that, can I assume that the preSend is a safer place for doing this?

Upvotes: 4

Views: 3868

Answers (1)

luboskrnac
luboskrnac

Reputation: 24581

Yes, preSend is called for all channel types (except NullChannel!) and is safest for your intentions.

You can find it in Spring Integration code here:

AbstractMessageChannel is abstract class for all channel types (except NullChannel) an is using preSend.

AbstractPollableChannel is using preReceive, which is parent of QueueChannel, RedezevousChannel and PriorityChannel.

So preReceive/postReceive/afterReceiveCompletion are not called for DirectChannel, ExecutorChannel and PublishSubscribeChannel.

Upvotes: 6

Related Questions