Updating reference documentation for M2.

This commit is contained in:
Mark Fisher
2008-02-28 00:12:52 +00:00
parent 4911ca69be
commit 8a6c4babee
2 changed files with 60 additions and 7 deletions

View File

@@ -105,10 +105,10 @@
to reference any Spring-managed object that implements the <interfacename>ChannelInterceptor</interfacename>
interface:
<programlisting><![CDATA[<channel id="exampleChannel">
<interceptor ref="trafficMonitoringInterceptor"/>
]]><emphasis><![CDATA[<interceptor ref="trafficMonitoringInterceptor"/>]]></emphasis><![CDATA[
</channel>]]></programlisting>
In general, it is a good idea to define the interceptors in a separate location since they usually provide
common behavior that can be reused across multiple channels.
In general, it is a good idea to define the interceptor implementations in a separate location since they
usually provide common behavior that can be reused across multiple channels.
</para>
</section>
@@ -129,16 +129,26 @@
In either case (<interfacename>MessageHandler</interfacename> or arbitrary object/method), when the handling
method returns a non-null value, the endpoint will attempt to send the reply message to an appropriate reply
channel. To determine the reply channel, it will first check for a value in the message header's
'replyChannelName' property. If that value is available, it will attempt to resolve the channel by performing a
'<literal>returnAddress</literal>' property. If that value is available, it will then check its type. If it is
a <classname>MessageChannel</classname>, the reply message will be sent to that channel. If it is a
<classname>String</classname>, then the endpoint will attempt to resolve the channel by performing a
lookup in the <interfacename>ChannelRegistry</interfacename>. If the message header does not contain a
'replyChannelName' property, then it will fallback to its own 'defaultOutputChannel' property. If neither is
available, then a <classname>MessageHandlingException</classname> will be thrown. To configure the default
output channel when using the XML namespace, provide the 'default-output-channel' attribute:
'returnAddress' property at all, then it will fallback to its own 'defaultOutputChannelName' property. If
neither is available, then a <classname>MessageHandlingException</classname> will be thrown. To configure the
default output channel when using the XML namespace, provide the 'default-output-channel' attribute:
<programlisting>&lt;endpoint input-channel="exampleChannel"
handler-ref="somePojo"
handler-method="someMethod"
default-output-channel="replyChannel"/&gt;</programlisting>
</para>
<para>
Endpoint's also support <interfacename>MessageSelectors</interfacename> as described in
<xref linkend="api-messageselector"/>. To configure selectors with namespace support, simply add one or more
&lt;selector&gt; sub-elements to the endpoint definition:
<programlisting><![CDATA[<endpoint id="endpoint" input-channel="channel" handler-ref="handler">
]]><emphasis><![CDATA[<selector ref="exampleSelector"/>]]></emphasis><![CDATA[
</endpoint>]]></programlisting>
</para>
<para>
When the <interfacename>MessageBus</interfacename> registers the endpoint, it will activate the subscription
by assigning the endpoint to the input channel's dispatcher. The dispatcher is capable of handling multiple

View File

@@ -398,4 +398,47 @@ public void registerHandler(String name, MessageHandler handler, Subscription su
single implementation: <classname>DefaultMessageEndpoint</classname>.
</para>
</section>
<section id="api-messageselector">
<title>MessageSelector</title>
<para>
As described above, when a <interfacename>MessageHandler</interfacename> 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
<emphasis>dynamic</emphasis> logic to determine what messages the handler should receive. The
<interfacename>MessageSelector</interfacename> strategy interface fulfills that role.
<programlisting><![CDATA[public interface MessageSelector {
boolean accept(Message<?> message);
}]]></programlisting>
A <interfacename>MessageEndpoint</interfacename> 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 <classname>PayloadTypeSelector</classname>
provides similar functionality to Datatype Channels (as described in <xref linkend="namespace-channel"/>)
except that in this case the type-matching can be done by the endpoint rather than the channel.
<programlisting><![CDATA[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)));
]]></programlisting>
Another simple but useful <interfacename>MessageSelector</interfacename> provided out-of-the-box is the
<classname>UnexpiredMessageSelector</classname>. As the name suggests, it only accepts messages that have
not yet expired.
</para>
<para>
Essentially, using a selector provides <emphasis>reactive</emphasis> routing whereas the Datatype Channel
and Message Router provide <emphasis>proactive</emphasis> routing. However, selectors accommodate additional
uses. For example, the <interfacename>MessageChannel</interfacename>'s 'purge' method accepts a selector:
<programlisting>channel.purge(someSelector);</programlisting>
There is even a <classname>ChannelPurger</classname> utility class whose purge operation is a good candidate for
Spring's JMX support:
<programlisting>ChannelPurger purger = new ChannelPurger(channel, new ExampleMessageSelector());
purger.purge();</programlisting>
</para>
<para>
Implementations of <interfacename>MessageSelector</interfacename> might provide opportunities for reuse on
channels in addition to endpoints. For that reason, Spring Integration provides a simple selector-wrapping
<interfacename>ChannelInterceptor</interfacename> that accepts one or more selectors in its constructor.
<programlisting>MessageSelectingInterceptor interceptor = new MessageSelectingInterceptor(selector1, selector2);
channel.addInterceptor(interceptor);</programlisting>
</para>
</section>
</chapter>