Files
spring-integration/spring-integration-reference/src/splitter.xml
2008-11-03 01:57:45 +00:00

142 lines
5.7 KiB
XML

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="splitter">
<title>Splitter</title>
<section id="splitter-annotation">
<title>Introduction</title>
<para>The Splitter is a component whose role is to partition a message in
several parts, and send the resulting messages to be processed
independently. Very often, they are upstream producers in a pipeline that
includes an Aggregator.</para>
</section>
<section>
<title>Functionality</title>
<para></para>
</section>
<section>
<title>Programming model</title>
<para>The API for performing splitting consists from one base class,
AbstractMessageSplitter, which is a MessageConsumer implementation,
encapsulating features which are common to splitters, such as filling in
the appropriate message headers CORRELATION_ID, SEQUENCE_SIZE, and
SEQUENCE_NUMBER on the messages that are produced. This allows to track
down the messages and the results of their processing (in a typical
scenario, these headers would be copied over to the messages that are
produced by the various transforming endpoints), and use them, for
example, in a Composed Message Processor scenario.</para>
<para>An excerpt from AbstractMessageSplitter can be seen below:</para>
<programlisting lang="java">public abstract class AbstractMessageSplitter
extends AbstractReplyProducingMessageConsumer {
...
protected abstract Object splitMessage(Message&lt;?&gt; message);
}</programlisting>
<para>For implementing a specific Splitter in an application, a developer
can extend AbstractMessageSplitter and implement the splitMessage method,
thus defining the actual logic for splitting the messages. The return
value can be one of the following:</para>
<itemizedlist>
<listitem>
<para>a Collection (or subclass thereof) or an array of Message
objects - in this case the messages will be sent as such (after the
CORRELATION_ID, SEQUENCE_SIZE and SEQUENCE_NUMBER will be populated).
Using this approach gives more control to the developer, for example
for populating custom message headers as part of the splitting
process.</para>
</listitem>
<listitem>
<para>a Collection (or subclass thereof) or an array of non-Message
objects - works like the prior case, except that each collection
element will be used as a Message payload. Using this approach allows
to focus on the</para>
</listitem>
<listitem>
<para>a Message or non-Message object (but not a Collection or an
Array) - it works like the previous cases, except that there is a
single message to be sent out.</para>
</listitem>
</itemizedlist>
<para>In Spring Integration, any POJO can implement the splitting
algorithm, provided that it defines a method that accepts a single
argument and has a return value. In this case, the return value of the
method will be interpreted as described above. The input argument might
either be a Message or a simple POJO. In the latter case, the splitter
will receive the payload of the incoming message. </para>
</section>
<section>
<title>Configuring a Splitter using XML</title>
<para>A splitter can be configured through XML as follows:<programlisting>&lt;channel id="inputChannel"/&gt;
&lt;splitter id="splitter" <co id="split1" />
ref="splitterBean" <co id="split2" />
method="split" <co id="split3" />
input-channel="inputChannel" <co id="split4" />
output-channel="outputChannel" <co id="split5" />/&gt;
&lt;channel id="outputChannel"/&gt;
&lt;beans:bean id="splitterBean" class="sample.PojoSplitter"/&gt;</programlisting><calloutlist>
<callout arearefs="split1">
<para>The id of the splitter is
<emphasis>optional</emphasis>.</para>
</callout>
<callout arearefs="split2">
<para>A reference to a bean defined in the application context. The
bean must implement the splitting logic as described in the section
above. <emphasis>Required</emphasis>.</para>
</callout>
<callout arearefs="split3">
<para>The method (defined on the bean specified above) that
implements the splitting logic.
<emphasis>Optional</emphasis>.</para>
</callout>
<callout arearefs="split4">
<para>The input channel of the splitter.
<emphasis>Required</emphasis>.</para>
</callout>
<callout arearefs="split5">
<para>The channel where the splitter will send the results of
splitting the incoming message. <emphasis>Optional (because incoming
messages can specify a reply channel themselves)</emphasis>.</para>
</callout>
</calloutlist></para>
</section>
<section>
<title>Configuring a Splitter with Annotations</title>
<para>The <interfacename>@Splitter</interfacename> annotation is
applicable to methods that expect either the
<interfacename>Message</interfacename> type or the message payload type,
and the return values of the method should be a collection of any type. If
the returned values are not actual <interfacename>Message</interfacename>
objects, then each of them will be sent as the payload of a message. Those
messages will be sent to the output channel as designated for the endpoint
on which the <interfacename>@Splitter</interfacename> is defined.
<programlisting language="java">@Splitter
List&lt;LineItem&gt; extractItems(Order order) {
return order.getItems()
}</programlisting></para>
</section>
</chapter>