Added Channel Adapter and Service Activator chapters
This commit is contained in:
59
spring-integration-reference/src/channel-adapter.xml
Normal file
59
spring-integration-reference/src/channel-adapter.xml
Normal file
@@ -0,0 +1,59 @@
|
||||
<?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="channel-adapter">
|
||||
<title>Channel Adapters</title>
|
||||
<para>
|
||||
Channel Adapters are Message Endpoints that enable connecting a single sender or receiver to a Message Channel.
|
||||
Spring Integration provides a number of adapters out of the box to support various transports, such as JMS, File,
|
||||
etc. Those will be discussed in upcoming chapters of this reference guide. However, this chapter focuses on the
|
||||
simple but flexible Method-invoking Channel Adapter support. There is an inbound and outbound adapter, and each
|
||||
may be configured with XML elements provided in the core namespace.
|
||||
</para>
|
||||
|
||||
<section id="channel-adapter-namespace-inbound">
|
||||
<title>The <inbound-channel-adapter> element</title>
|
||||
<para>
|
||||
An "inbound-channel-adapter" element can invoke any method on a Spring-managed Object and send a non-null return
|
||||
value to a <interfacename>MessageChannel</interfacename> after converting it to a <classname>Message</classname>.
|
||||
When the adapter's subscription is activated, a poller will attempt to receive messages from the source. The
|
||||
poller will be scheduled with the <interfacename>TaskScheduler</interfacename> according to the provided
|
||||
configuration. To configure the polling 'interval' or 'cronExpression' for an individual channel-adapter's
|
||||
schedule, provide a 'poller' element with either an 'interval-trigger' (in milliseconds) or 'cron-trigger'
|
||||
sub-element:
|
||||
<programlisting language="xml"><![CDATA[<inbound-channel-adapter ref="source1" method="method1" channel="channel1">
|
||||
<poller>
|
||||
<interval-trigger interval="5000"/>
|
||||
</poller>
|
||||
</inbound-channel-adapter>
|
||||
|
||||
<inbound-channel-adapter ref="source2" method="method2" channel="channel2">
|
||||
<poller>
|
||||
<cron-trigger expression="30 * * * * MON-FRI"/>
|
||||
</poller>
|
||||
</channel-adapter>]]></programlisting>
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="channel-adapter-namespace-outbound">
|
||||
<title>The <outbound-channel-adapter/> element</title>
|
||||
<para>
|
||||
An "outbound-channel-adapter" element can also connect a <interfacename>MessageChannel</interfacename> to any
|
||||
method that should be invoked with the payload of any Message sent to that channel.
|
||||
<programlisting language="xml"><![CDATA[<outbound-channel-adapter channel="channel1" ref="target1" method="method1"/>]]></programlisting>
|
||||
If the channel being adapted is a <interfacename>PollableChannel</interfacename>, provide a poller sub-element:
|
||||
<programlisting language="xml"><![CDATA[<outbound-channel-adapter channel="channel2" ref="target2" method="method2">
|
||||
]]><emphasis><![CDATA[<poller>
|
||||
<interval-trigger interval="3000"/>
|
||||
</poller>]]></emphasis><![CDATA[
|
||||
</outbound-channel-adapter>]]></programlisting>
|
||||
</para>
|
||||
<para>
|
||||
Any Channel Adapter can be created without a "channel" reference in which case it will implicitly create an
|
||||
instance of <classname>DirectChannel</classname>. The created channel's name will match the "id" attribute
|
||||
of the <inbound-channel-adapter/> or <outbound-channel-adapter>l; element. Therefore, if the "channel"
|
||||
is not provided, the "id" is required.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
</chapter>
|
||||
@@ -84,197 +84,47 @@
|
||||
main thing to recognize is the consistency of the naming for each namespace URI and schema location.
|
||||
</para>
|
||||
|
||||
<section id="namespace-endpoint">
|
||||
<title>Configuring Message Endpoints</title>
|
||||
<para>
|
||||
Each of the endpoint types (channel-adapter, service-activator, etc) has its own element in the namespace.
|
||||
</para>
|
||||
<section id="namespace-endpoint-inboundchanneladapter">
|
||||
<title>The inbound <channel-adapter/> element with a MessageSource</title>
|
||||
<para>
|
||||
A "channel-adapter" element can connect any implementation of the <interfacename>MessageSource</interfacename>
|
||||
interface to a <interfacename>MessageChannel</interfacename>. When the <interfacename>MessageBus</interfacename>
|
||||
registers the endpoint, it will activate the subscription and if necessary create a poller for the endpoint.
|
||||
The Message Bus delegates to a <interfacename>TaskScheduler</interfacename> for scheduling the poller based
|
||||
on its schedule. To configure the polling 'period' or 'cronExpression' for an individual channel-adapter's
|
||||
schedule, provide a 'poller' sub-element with the 'period' (in milliseconds) or 'cron' attribute:
|
||||
<programlisting language="xml"><![CDATA[<channel-adapter source="source1" channel="channel1">
|
||||
<poller period="5000"/>
|
||||
</channel-adapter>
|
||||
|
||||
<channel-adapter source="source2" channel="channel2">
|
||||
<poller cron="30 * * * * ?"/>
|
||||
</channel-adapter>]]></programlisting>
|
||||
</para>
|
||||
</section>
|
||||
<section id="namespace-endpoint-outboundchanneladapter">
|
||||
<title>The outbound <channel-adapter/> with a MessageTarget</title>
|
||||
<para>
|
||||
A "channel-adapter" element can also connect a <interfacename>MessageChannel</interfacename> to any implementation
|
||||
of the <interfacename>MessageTarget</interfacename> interface.
|
||||
<programlisting language="xml"><![CDATA[<channel-adapter channel="exampleChannel" target="exampleTarget"/>]]></programlisting>
|
||||
Again, it is possible to provide a poller:
|
||||
<programlisting language="xml"><![CDATA[<channel-adapter channel="exampleChannel" target="exampleTarget">
|
||||
]]><emphasis><![CDATA[<poller period="3000"/>]]></emphasis><![CDATA[
|
||||
</channel-adapter>]]></programlisting>
|
||||
</para>
|
||||
</section>
|
||||
<section id="namespace-service-activator">
|
||||
<title>The <service-activator/> element</title>
|
||||
<para>
|
||||
To create a Service Activator, use the 'service-activator' element with the 'input-channel' and
|
||||
'ref' attributes:
|
||||
<programlisting language="xml"><service-activator input-channel="exampleChannel" ref="exampleHandler"/></programlisting>
|
||||
</para>
|
||||
<para>
|
||||
The configuration above assumes that "exampleHandler" either contains a single method annotated with the
|
||||
@ServiceActivator annotation or that it contains a single public method period. To delegate to an explicitlye
|
||||
defined method of any object, simply add the "method" attribute.
|
||||
<programlisting language="xml"><service-activator input-channel="exampleChannel" ref="somePojo" method="someMethod"/></programlisting>
|
||||
</para>
|
||||
<para>
|
||||
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 if the <literal>NEXT_TARGET</literal> header contains
|
||||
a non-null value, next it will check if an "output-channel" was provided in the endpoint configuration:
|
||||
<programlisting language="xml"><service-activator input-channel="exampleChannel" output-channel="replyChannel"
|
||||
ref="somePojo" method="someMethod"/></programlisting>
|
||||
If no "output-channel" is available, it will finally check the message header's <literal>RETURN_ADDRESS</literal>
|
||||
property. If that value is available, it will then check its type. If it is a <classname>MessageTarget</classname>,
|
||||
the reply message will be sent to that target. 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 target cannot be resolved, then a <classname>MessageHandlingException</classname> will be thrown.
|
||||
</para>
|
||||
</section>
|
||||
<para>
|
||||
Message Endpoints also support <interfacename>MessageSelectors</interfacename>. To configure a selector with
|
||||
namespace support, simply add the "selector" attribute to the endpoint definition and reference an
|
||||
implementation of the <interfacename>MessageSelector</interfacename> interface.
|
||||
<programlisting language="xml"><![CDATA[<service-activator id="endpoint" input-channel="channel" ref="handler"
|
||||
selector="exampleSelector"/>]]></programlisting>
|
||||
</para>
|
||||
<para>
|
||||
Spring Integration also provides transaction support for the pollers so that each receive-and-forward
|
||||
operation can be performed as an atomic unit-of-work. To configure transactions for a poller, simply
|
||||
add the <transactional/> sub-element. The attributes for this element should be familiar to anyone
|
||||
who has experience with Spring's Transaction management:
|
||||
<programlisting language="xml"><![CDATA[<service-activator id="exampleEndpoint"
|
||||
input-channel="requestChannel"
|
||||
ref="someObject"
|
||||
method="someMethod"
|
||||
output-channel="replyChannel">
|
||||
<poller period="1000">
|
||||
<transactional transaction-manager="txManager"
|
||||
propagation="REQUIRES_NEW"
|
||||
isolation="REPEATABLE_READ"
|
||||
timeout="10000"
|
||||
read-only="false"/>
|
||||
</poller>
|
||||
</service-activator>]]></programlisting>
|
||||
</para>
|
||||
<para>
|
||||
Spring Integration also provides support for executing the pollers with a
|
||||
<interfacename>TaskExceutor</interfacename>. This enables concurrency for an endpoint or group of
|
||||
endpoints. As a convenience, there is also namespace support for creating a simple thread pool executor.
|
||||
The <pool-executor/> element defines attributes for common concurrency settings such as core-size,
|
||||
max-size, and queue-capacity. Configuring a thread-pooling executor can make a substantial difference in
|
||||
how the endpoint performs under load. These settings are available per-endpoint since the performance
|
||||
characteristics of an endpoint's handler or is one of the major factors to consider (the other major factor
|
||||
being the expected volume on the channel to which the endpoint subscribes). To enable concurrency for an
|
||||
endpoint that is configured with the XML namespace support, provide the 'task-executor' reference on its
|
||||
<poller/> element and then provide one or more of the properties shown below:
|
||||
<programlisting language="xml"><![CDATA[<service-activator input-channel="exampleChannel" ref="exampleHandler">
|
||||
<poller period="5000" task-executor="pool"/>
|
||||
</service-activator>
|
||||
|
||||
<pool-executor id="pool" core-size="5" max-size="25" queue-capacity="20" keep-alive-seconds="120"/>]]></programlisting>
|
||||
If no 'task-executor' is provided, the endpoint's handler or target will be invoked in the caller's thread.
|
||||
Note that the "caller" is usually the MessageBus' task scheduler except in the case of a subscribable channel.
|
||||
Also, keep in mind that you the 'task-executor' attribute can provide a reference to any implementation of
|
||||
Spring's <interfacename>TaskExecutor</interfacename> interface.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="namespace-messagebus">
|
||||
<title>Configuring the Message Bus</title>
|
||||
<para>
|
||||
The Message Bus plays a central role, but its configuration is quite simple since it is primarily concerned
|
||||
with managing internal details based on the configuration of channels and endpoints. The bus is aware of its
|
||||
host application context, and therefore is also capable of auto-detecting the channels and endpoints.
|
||||
The Message Bus can be configured with a single empty element:
|
||||
<programlisting language="xml"><message-bus/></programlisting>
|
||||
</para>
|
||||
<para>
|
||||
The Message Bus provides default error handling for its components in the form of a configurable error channel,
|
||||
and it will first check for a channel bean named 'errorChannel' within the context:
|
||||
<programlisting language="xml"><![CDATA[<message-bus/>
|
||||
<title>Configuring the Message Bus</title>
|
||||
<para>
|
||||
The Message Bus plays a central role, but its configuration is quite simple since it is primarily concerned
|
||||
with managing internal details based on the configuration of channels and endpoints. The bus is aware of its
|
||||
host application context, and therefore is also capable of auto-detecting the channels and endpoints.
|
||||
The Message Bus can be configured with a single empty element:
|
||||
<programlisting language="xml"><message-bus/></programlisting>
|
||||
</para>
|
||||
<para>
|
||||
The Message Bus provides default error handling for its components in the form of a configurable error channel,
|
||||
and it will first check for a channel bean named 'errorChannel' within the context:
|
||||
<programlisting language="xml"><![CDATA[<message-bus/>
|
||||
|
||||
<channel id="errorChannel" capacity="500"/>]]></programlisting>
|
||||
When exceptions occur in a scheduled poller task's execution, those exceptions will be wrapped in
|
||||
<classname>ErrorMessages</classname> and sent to the 'errorChannel' by default. To enable global error
|
||||
handling, simply register a handler on that channel. For example, you can configure Spring Integration's
|
||||
<classname>RootCauseErrorMessageRouter</classname> as the handler of an endpoint that is subscribed to the
|
||||
'errorChannel'. That router can then spread the error messages across multiple channels based on
|
||||
<classname>Exception</classname> type. However, since most of the errors will already have been wrapped in
|
||||
<classname>MessageDeliveryException</classname> or <classname>MessageHandlingException</classname>,
|
||||
the <classname>RootCauseErrorMessageRouter</classname> is typically a better option.
|
||||
</para>
|
||||
<para>
|
||||
The 'message-bus' element accepts several more optional attributes. First, you can control whether the
|
||||
<classname>MessageBus</classname> will be started automatically (the default) or will require explicit startup
|
||||
by invoking its <methodname>start()</methodname> method (<classname>MessageBus</classname> implements
|
||||
Spring's <interfacename>Lifecycle</interfacename> interface):
|
||||
<programlisting language="xml"><![CDATA[<message-bus auto-startup="false"/>]]></programlisting>
|
||||
</para>
|
||||
<para>
|
||||
Another configurable property is the size of the default dispatcher thread pool. The dispatcher threads are
|
||||
responsible for polling channels and then passing the messages to handlers.
|
||||
<programlisting language="xml"><![CDATA[<message-bus dispatcher-pool-size="25"/>]]></programlisting>
|
||||
When the endpoints are concurrency-enabled as described in the previous section, the invocation of the handling
|
||||
methods will happen within the handler thread pool and not the dispatcher pool. However, when no task-executor
|
||||
is provided to an endpoint's poller, then it will be invoked in the dispatcher's thread (with the exception of
|
||||
subscribable channels).
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="namespace-adapters">
|
||||
<title>Configuring Adapters</title>
|
||||
<para>
|
||||
The most convenient way to configure Source and Target adapters is by using the namespace support. The
|
||||
following examples demonstrate the namespace-based configuration of several source, target, gateway,
|
||||
and handler adapters:
|
||||
<programlisting language="xml"><![CDATA[<mail-target id="mailTarget" host="somehost" username="someuser" password="somepassword"/>
|
||||
|
||||
<ws-handler id="wsTarget" uri="http://example.org" channel="wsOutput"/>
|
||||
]]></programlisting>
|
||||
</para>
|
||||
<para>
|
||||
In the examples above, notice that simple implementations of the <interfacename>MessageSource</interfacename>
|
||||
and <interfacename>MessageTarget</interfacename> interfaces do not accept any 'channel' references. To
|
||||
connect such sources and targets to a channel, register them within a 'channel-adapter'. For example, here
|
||||
is a File source with an endpoint whose polling will be scheduled to execute every 30 seconds by the
|
||||
<classname>MessageBus</classname>.
|
||||
<programlisting language="xml"><![CDATA[<channel-adapter source="fileSource" channel="exampleChannel">
|
||||
<poller period="30000"/>
|
||||
</channel-adapter>
|
||||
|
||||
<file-source id="fileSource" directory="/tmp/in"/>
|
||||
]]></programlisting>
|
||||
When exceptions occur in a scheduled poller task's execution, those exceptions will be wrapped in
|
||||
<classname>ErrorMessages</classname> and sent to the 'errorChannel' by default. To enable global error
|
||||
handling, simply register a handler on that channel. For example, you can configure Spring Integration's
|
||||
<classname>ErrorMessageExceptionTypeRouter</classname> as the handler of an endpoint that is subscribed to the
|
||||
'errorChannel'. That router can then spread the error messages across multiple channels based on
|
||||
<classname>Exception</classname> type. However, since most of the errors will already have been wrapped in
|
||||
<classname>MessageDeliveryException</classname> or <classname>MessageHandlingException</classname>,
|
||||
the <classname>ErrorMessageExceptionTypeRouter</classname> is typically a better option.
|
||||
</para>
|
||||
|
||||
|
||||
|
||||
|
||||
<para>
|
||||
Any Channel Adapter can be created without a "channel" reference in which case it will implicitly create an
|
||||
instance of <classname>DirectChannel</classname>. The created channel's name will match the "id" attribute
|
||||
of the <channel-adapter/> element. Therefore, if the "channel" is not provided, the "id" is required.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
|
||||
<para>
|
||||
The 'message-bus' element accepts several more optional attributes. First, you can control whether the
|
||||
<classname>MessageBus</classname> will be started automatically (the default) or will require explicit startup
|
||||
by invoking its <methodname>start()</methodname> method (<classname>MessageBus</classname> implements
|
||||
Spring's <interfacename>Lifecycle</interfacename> interface):
|
||||
<programlisting language="xml"><![CDATA[<message-bus auto-startup="false"/>]]></programlisting>
|
||||
</para>
|
||||
<para>
|
||||
Another configurable property is the reference to a <interfacename>TaskScheduler</interfacename> implementation.
|
||||
If not provided, a default will be created. The scheduler is responsible for managing the pollers.
|
||||
<programlisting language="xml"><![CDATA[<message-bus task-scheduler="someScheduler"/>]]></programlisting>
|
||||
When the endpoints are concurrency-enabled with their own 'taskExecutor' reference, the invocation of the handling
|
||||
methods will happen within that executor's thread pool and not the main scheduler pool. However, when no
|
||||
task-executor is provided for an endpoint's poller, then it will be invoked in the dispatcher's thread
|
||||
(with the exception of subscribable channels where the subscribers may be invoked directly).
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="annotations">
|
||||
<title>Annotations</title>
|
||||
|
||||
45
spring-integration-reference/src/service-activator.xml
Normal file
45
spring-integration-reference/src/service-activator.xml
Normal file
@@ -0,0 +1,45 @@
|
||||
<?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="service-activator">
|
||||
<title>Service Activator</title>
|
||||
|
||||
<section id="service-activator-introduction">
|
||||
<title>Introduction</title>
|
||||
<para>
|
||||
The Service Activator is the endpoint type for connecting any Spring-managed Object to an input channel so that
|
||||
it may play the role of a service. If the service produces output, it may also be connected to an output channel.
|
||||
Alternatively, an output producing service may be located at the end of a processing pipeline or message flow in
|
||||
which case, the inbound Message's "replyChannel" header can be used. This is the default behavior if no output
|
||||
channel is defined, and as with most of the configuration options you'll see here, the same behavior actually
|
||||
applies for most of the other components we have seen.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="service-activator-namespace">
|
||||
<title>The <service-activator/> Element</title>
|
||||
<para>
|
||||
To create a Service Activator, use the 'service-activator' element with the 'input-channel' and 'ref' attributes:
|
||||
<programlisting language="xml"><service-activator input-channel="exampleChannel" ref="exampleHandler"/></programlisting>
|
||||
</para>
|
||||
<para>
|
||||
The configuration above assumes that "exampleHandler" either contains a single method annotated with the
|
||||
@ServiceActivator annotation or that it contains only one public method at all. To delegate to an explicitly
|
||||
defined method of any object, simply add the "method" attribute.
|
||||
<programlisting language="xml"><service-activator input-channel="exampleChannel" ref="somePojo" method="someMethod"/></programlisting>
|
||||
</para>
|
||||
<para>
|
||||
In either case, when the service 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 if an
|
||||
"output-channel" was provided in the endpoint configuration:
|
||||
<programlisting language="xml"><service-activator input-channel="exampleChannel" output-channel="replyChannel"
|
||||
ref="somePojo" method="someMethod"/></programlisting>
|
||||
If no "output-channel" is available, it will then check the Message's <literal>RETURN_ADDRESS</literal> header
|
||||
value. If that value is available, it will then check its type. If it is a
|
||||
<interfacename>MessageChannel</interfacename>, 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 name to a channel instance.
|
||||
If the channel cannot be resolved, then a <classname>ChannelResolutionException</classname> will be thrown.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
</chapter>
|
||||
@@ -44,6 +44,8 @@
|
||||
<xi:include href="./message.xml"/>
|
||||
<xi:include href="./channel.xml"/>
|
||||
<xi:include href="./endpoint.xml"/>
|
||||
<xi:include href="./service-activator.xml"/>
|
||||
<xi:include href="./channel-adapter.xml"/>
|
||||
<xi:include href="./router.xml"/>
|
||||
<xi:include href="./transformation.xml"/>
|
||||
<xi:include href="./splitter.xml"/>
|
||||
|
||||
Reference in New Issue
Block a user