As described above, when a MessageHandler
is registered with the message bus, it
is hosted by an endpoint and thereby subscribed to a channel. Often it is necessary to provide additional
dynamic logic to determine what messages the handler should receive. The
MessageSelector
strategy interface fulfills that role.
public interface MessageSelector { boolean accept(Message<?> message); }
A MessageEndpoint
can be configured with zero or more selectors, 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 the section called “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, the MessageChannel
's 'purge' method accepts a selector:
channel.purge(someSelector);
There is even 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);