75 lines
4.5 KiB
XML
75 lines
4.5 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="chain">
|
|
<title>Message Handler Chain</title>
|
|
|
|
<section id="chain-introduction">
|
|
<title>Introduction</title>
|
|
<para>
|
|
The <classname>MessageHandlerChain</classname> is an implementation of
|
|
<interfacename>MessageHandler</interfacename> that can be configured as a single Message Endpoint while
|
|
actually delegating to a chain of other handlers, such as Filters, Transformers, Splitters, and so on.
|
|
This can lead to a much simpler configuration when several handlers need to be connected in a fixed, linear
|
|
progression. For example, it is fairly common to provide a Transformer before other components. Similarly, when
|
|
providing a <emphasis>Filter</emphasis> before some other component in a chain, you are essentially creating a
|
|
<ulink url="http://www.eaipatterns.com/MessageSelector.html">Selective Consumer</ulink>. In either case, the
|
|
chain only requires a single input-channel and a single output-channel as opposed to the configuration of
|
|
channels for each individual component.
|
|
<tip>
|
|
Spring Integration's <emphasis>Filter</emphasis> provides a boolean property 'throwExceptionOnRejection'. When
|
|
providing multiple Selective Consumers on the same point-to-point channel with different acceptance criteria,
|
|
this value should be set to 'true' (the default is false) so that the dispatcher will know that the Message was
|
|
rejected and as a result will attempt to pass the Message on to other subscribers. If the Exception were not
|
|
thrown, then it would appear to the dispatcher as if the Message had been passed on successfully even though
|
|
the Filter had <emphasis>dropped</emphasis> the Message to prevent further processing.
|
|
</tip>
|
|
</para>
|
|
<para>
|
|
The handler chain simplifies configuration while internally maintaining the same degree of loose coupling between
|
|
components, and it is trivial to modify the configuration if at some point a non-linear arrangement is required.
|
|
</para>
|
|
<para>
|
|
Internally, the chain will be expanded into a linear setup of the listed endpoints, separated by direct channels.
|
|
The reply channel header will not be taken into account within the chain: only after the last handler is invoked
|
|
will the resulting message be forwarded on to the reply channel or the chain's output channel. Because of this
|
|
setup all handlers except the last require a <methodname>setOutputChannel</methodname> implementation. The last
|
|
handler only needs an output channel if the outputChannel on the MessageHandlerChain is set.
|
|
<note>
|
|
<para>
|
|
As with other endpoints, the output-channel is optional. If there is a reply Message at the end of the
|
|
chain, the output-channel takes precedence, but if not available, the chain handler will check for a
|
|
reply channel header on the inbound Message.
|
|
</para>
|
|
</note>
|
|
</para>
|
|
<para>
|
|
In most cases there is no need to implement MessageHandlers yourself. The next section will focus on namespace
|
|
support for the chain element. Most Spring Integration endpoints, like Service Activators and Transformers, are
|
|
suitable for use within a <classname>MessageHandlerChain</classname>.
|
|
</para>
|
|
</section>
|
|
|
|
<section id="chain-namespace">
|
|
<title>The <chain> Element</title>
|
|
<para>
|
|
The <chain> element provides an 'input-channel' attribute, and if the last element in the chain is capable
|
|
of producing reply messages (optional), it also supports an 'output-channel' attribute. The sub-elements are then
|
|
filters, transformers, splitters, and service-activators. The last element may also be a router.
|
|
<programlisting language="xml"><![CDATA[ <chain input-channel="input" output-channel="output">
|
|
<filter ref="someSelector" throw-exception-on-rejection="true"/>
|
|
<header-enricher error-channel="customErrorChannel">
|
|
<header name="foo" value="bar"/>
|
|
</header-enricher>
|
|
<service-activator ref="someService" method="someMethod"/>
|
|
</chain>]]></programlisting>
|
|
</para>
|
|
<para>
|
|
The <header-enricher> element used in the above example will set a message header with name "foo" and
|
|
value "bar" on the message. A header enricher is a specialization of Transformer that touches only header
|
|
values. You could obtain the same result by implementing a MessageHandler that did the header modifications
|
|
and wiring that as a bean.
|
|
</para>
|
|
</section>
|
|
|
|
</chapter> |