As described above, each endpoint is registered with the message bus and is thereby subscribed
to a channel. Often it is necessary to provide additional dynamic logic to
determine what messages the endpoint should receive. The MessageSelector
strategy interface fulfills that role.
public interface MessageSelector { boolean accept(Message<?> message); }
A MessageEndpoint
can be configured with a selector (or selector-chain)
and will only receive messages that are accepted by each selector. Even though the interface is simple
to implement, a couple common selector implementations are provided. For example, the
PayloadTypeSelector
provides similar functionality to Datatype Channels
(as described in Section 4.2.1, “Configuring Message Channels”) except that in this case the type-matching can be done
by the endpoint rather than the channel.
PayloadTypeSelector selector = new PayloadTypeSelector(String.class, Integer.class); assertTrue(selector.accept(new StringMessage("example"))); assertTrue(selector.accept(new GenericMessage<Integer>(123))); assertFalse(selector.accept(new GenericMessage<SomeObject>(someObject)));
Another simple but useful MessageSelector
provided out-of-the-box is the
UnexpiredMessageSelector
. As the name suggests, it only accepts messages that have
not yet expired.
Essentially, using a selector provides reactive routing whereas the Datatype Channel
and Message Router provide proactive routing. However, selectors accommodate additional
uses. For example, a PollableChannel
's 'purge' method accepts a selector:
channel.purge(someSelector);
There is a ChannelPurger
utility class whose purge operation is a good candidate for
Spring's JMX support:
ChannelPurger purger = new ChannelPurger(new ExampleMessageSelector(), channel); purger.purge();
Implementations of MessageSelector
might provide opportunities for reuse on
channels in addition to endpoints. For that reason, Spring Integration provides a simple selector-wrapping
ChannelInterceptor
that accepts one or more selectors in its constructor.
MessageSelectingInterceptor interceptor =
new MessageSelectingInterceptor(selector1, selector2);
channel.addInterceptor(interceptor);