Updated adapters documentation.

This commit is contained in:
Mark Fisher
2008-07-08 04:31:11 +00:00
parent a22d205008
commit 58eda9089b

View File

@@ -6,24 +6,33 @@
<section id="adapters-intro">
<title>Introduction</title>
<para>
Spring Integration provides a number of implementations of the <interfacename>Source</interfacename> and
<interfacename>Target</interfacename> interfaces that serve as adapters for interacting with external
systems or components that are not part of the messaging system. Configuring these source and target
implementations within <classname>SourceEndpoints</classname> and <classname>TargetEndpoints</classname>
provides an implementation of the <emphasis>Channel Adapter</emphasis> pattern. Essentially, the external
system or component sends-to and/or receives-from a <interfacename>MessageChannel</interfacename>. In the
1.0 Milestone 4 release, Spring Integration includes source and target implementations for JMS, RMI,
Files, Streams, Spring's HttpInvoker and Spring ApplicationEvents. A source adapter for FTP is
also available as well as target adapters for sending e-mail and invoking Web Services.
Spring Integration provides a number of implementations of the <interfacename>MessageSource</interfacename>
and <interfacename>MessageTarget</interfacename> interfaces that serve as adapters for interacting with
external systems or components that are not part of the messaging system. These source and target
implementations can be configured within the same <emphasis>channel-adapter</emphasis> element that we
have already discussed. Essentially, the external system or component sends-to and/or receives-from a
<interfacename>MessageChannel</interfacename>. In the 1.0 Milestone 5 release, Spring Integration includes
source and target implementations for JMS, Files, Streams, and Spring ApplicationEvents. A source adapter
for FTP is also available.
</para>
<para>
Adapters that allow the external system to perform request-reply operations across Spring Integration
Adapters that allow an external system to perform request-reply operations across Spring Integration
<interfacename>MessageChannels</interfacename> are actually examples of the <emphasis>Messaging Gateway</emphasis>
pattern. Therefore, those implementations are typically called "gateways". For example, Spring Integration
provides a <classname>JmsSource</classname> that is <emphasis>polled by</emphasis> the bus-managed
scheduler, but it also provides a <classname>JmsGateway</classname>. The gateway differs from the source in
that it is an <emphasis>event-driven consumer</emphasis> rather than a <emphasis>polling consumer</emphasis>,
and it is capable of waiting for reply messages.
pattern. Therefore, those implementations are typically called "gateways" (whereas "source" and "target"
are in-only and out-only interactions respectively). For example, Spring Integration provides a
<classname>JmsSource</classname> that is <emphasis>polled by</emphasis> the bus-managed scheduler, but
also provides a <classname>JmsGateway</classname>. The gateway differs from the source in that it is an
<emphasis>event-driven consumer</emphasis> rather than a <emphasis>polling consumer</emphasis>,
and it is capable of waiting for reply messages. Spring Integration also provides gateways for RMI and
Spring's HttpInvoker.
</para>
<para>
Finally, adapters that enable interaction with external systems by <emphasis>invoking them</emphasis> for
request/reply interactions (the response is sent back on a Message Channel) are typically called
<emphasis>handlers</emphasis> in Spring Integration, since they implement the
<interfacename>MessageHandler</interfacename> interface. Basically, these types of adapters can be
configured exactly like any POJO with the &lt;service-activator&gt; element. Spring Integration provides
RMI, HttpInvoker, and Web Service handler implementations.
</para>
<para>
All of these adapters are discussed in this section. However, namespace support is provided for many of them
@@ -44,7 +53,7 @@
The <classname>JmsSource</classname> requires a reference to either a single <classname>JmsTemplate</classname>
instance or both <interfacename>ConnectionFactory</interfacename> and <interfacename>Destination</interfacename>
(a 'destinationName' can be provided in place of the 'destination' reference). The <classname>JmsSource</classname>
can then be referenced from a <classname>SourceEndpoint</classname> that connects the source to a
can then be referenced from a "channel-adapter" element that connects the source to a
<interfacename>MessageChannel</interfacename> instance. The following example defines a JMS source with
a <classname>JmsTemplate</classname> as a constructor-argument.
<programlisting language="xml"><![CDATA[<bean id="jmsSource" class="org.springframework.integration.adapter.jms.JmsSource">
@@ -77,42 +86,42 @@
<section id="adapters-rmi">
<title>RMI Adapters</title>
<para>
The <classname>RmiSourceAdapter</classname> is built upon Spring's <classname>RmiServiceExporter</classname>.
The <classname>RmiGateway</classname> is built upon Spring's <classname>RmiServiceExporter</classname>.
However, since it is adapting a <interfacename>MessageChannel</interfacename>, there is no need to specify
the <emphasis>serviceInterface</emphasis>. Likewise, the <emphasis>serviceName</emphasis> is automatically
generated based on the channel name. Therefore, creating the adapter is as simple as providing a reference
to its channel: <programlisting language="java">RmiSourceAdapter rmiSourceAdapter = new RmiSourceAdapter(channel);
to its channel: <programlisting language="java">RmiGateway rmiGateway = new RmiGateway(channel);
</programlisting>
</para>
<para>
The <classname>RmiTargetAdapter</classname> encapsulates the creation of a proxy that is capable of
communicating with an <classname>RmiSourceAdapter</classname> running in another process. Since the interface
The <classname>RmiHandler</classname> encapsulates the creation of a proxy that is capable of
communicating with an <classname>RmiGateway</classname> running in another process. Since the interface
is already known, the only required information is the URL. The URL should include the host, port (default is
'1099'), and 'serviceName'. The 'serviceName' must match that created by the
<classname>RmiSourceAdapter</classname> (the prefix is available as a constant).
<programlisting language="java">String url = "http://somehost:1099/" + RmiSourceAdapter.SERVICE_NAME_PREFIX + "someChannel";
RmiTargetAdapter rmiTargetAdapter = new RmiTargetAdapter(url);
<classname>RmiGateway</classname> (the prefix is available as a constant).
<programlisting language="java">String url = "http://somehost:1099/" + RmiGateway.SERVICE_NAME_PREFIX + "someChannel";
RmiHandler rmiHandler = new RmiHandler(url);
</programlisting>
</para>
</section>
<section id="adapters-httpinvoker">
<title>HttpInvoker Adapters</title>
<para>
The source and target adapters for HttpInvoker are very similar to the RMI adapters. For a source, only the
The adapters for HttpInvoker are very similar to the RMI adapters. For a source, only the
channel needs to be provided, and for a target, only the URL. If running in a Spring MVC environment, then
the <classname>HttpInvokerSourceAdapter</classname> simply needs to be defined and provided in a
the <classname>HttpInvokerGateway</classname> simply needs to be defined and provided in a
<interfacename>HandlerMapping</interfacename>. For example, the following would be exposed at the path
"http://somehost/path-mapped-to-dispatcher-servlet/httpInvokerAdapter" when a simple
<classname>BeanNameUrlHandlerMapping</classname> strategy is enabled:
<programlisting language="xml"><![CDATA[<bean name="/httpInvokerAdapter"
class="org.springframework.integration.adapter.httpinvoker.HttpInvokerSourceAdapter">
class="org.springframework.integration.adapter.httpinvoker.HttpInvokerGateway">
<constructor-arg ref="someChannel"/>
</bean>]]></programlisting>
When not running in a Spring MVC application, simply define a servlet in 'web.xml' whose type is
<classname>HttpRequestHandlerServlet</classname> and whose name matches the bean name of the source
adapter. As with the <classname>RmiTargetAdapter</classname>, the
<classname>HttpInvokerTargetAdapter</classname> only requires the URL that matches an instance of
<classname>HttpInvokerSourceAdapter</classname> running in a web application.
adapter. As with the <classname>RmiHandler</classname>, the
<classname>HttpInvokerHandler</classname> only requires the URL that matches an instance of
<classname>HttpInvokerGateway</classname> running in a web application.
</para>
</section>
<section id="adapters-file">
@@ -121,7 +130,7 @@ RmiTargetAdapter rmiTargetAdapter = new RmiTargetAdapter(url);
The <classname>FileSource</classname> requires the directory as a constructor argument:
<programlisting language="java">public FileSource(File directory)</programlisting>
It can then be connected to a <interfacename>MessageChannel</interfacename> when referenced from
a <classname>SourceEndpoint</classname>.
a "channel-adapter" element.
</para>
<para>
The <classname>FileTarget</classname> constructor also requires the 'directory' argument. The target
@@ -133,10 +142,10 @@ RmiTargetAdapter rmiTargetAdapter = new RmiTargetAdapter(url);
<title>FTP Adapters</title>
<para>
To poll a directory with FTP, configure an instance of <classname>FtpSource</classname> and then connect
it to a channel by configuring a <classname>SourceEndpoint</classname>. The <classname>FtpSource</classname>
it to a channel by configuring a <classname>channel-adapter</classname>. The <classname>FtpSource</classname>
expects a number of properties for connecting to the FTP server as shown below.
<programlisting language="xml"><![CDATA[<bean id="ftpSource"
class="org.springframework.integration.adapter.ftp.FtpSourceAdapter">
class="org.springframework.integration.adapter.ftp.FtpSource">
<property name="host" value="example.org"/>
<property name="username" value="someuser"/>
<property name="password" value="somepassword"/>
@@ -174,8 +183,8 @@ MailAttributeKeys.REPLY_TO</programlisting>
A static implementation is also available out-of-the-box and may be useful for testing. However, when
customizing, the properties would typically be generated dynamically based on the message itself. The
following is an example of a configured mail adapter.
<programlisting language="xml"><![CDATA[<bean id="mailTargetAdapter"
class="org.springframework.integration.adapter.mail.MailTargetAdapter">
<programlisting language="xml"><![CDATA[<bean id="mailTarget"
class="org.springframework.integration.adapter.mail.MailTarget">
<property name="mailSender" ref="javaMailSender"/>
<property name="headerGenerator" ref="dynamicMailMessageHeaderGenerator"/>
</bean>]]></programlisting>
@@ -185,19 +194,19 @@ MailAttributeKeys.REPLY_TO</programlisting>
<title>Web Service Adapters</title>
<para>
To invoke a Web Service upon sending a message to a channel, there are two options:
<classname>SimpleWebServiceTargetAdapter</classname> and
<classname>MarshallingWebServiceTargetAdapter</classname>. The former will accept either a
<classname>SimpleWebServiceHandler</classname> and
<classname>MarshallingWebServiceHandler</classname>. The former will accept either a
<classname>String</classname> or <interfacename>javax.xml.transform.Source</interfacename> as the message
payload. The latter provides support for any implementation of the <interfacename>Marshaller</interfacename>
and <interfacename>Unmarshaller</interfacename> interfaces. Both require the URI of the Web Service to be
called.<programlisting language="java">simpleAdapter = new SimpleWebServiceTargetAdapter(uri);
called.<programlisting language="java">simpleHandler = new SimpleWebServiceHandler(uri);
marshallingAdapter = new MarshallingWebServiceTargetAdapter(uri, marshaller);
marshallingHandler = new MarshallingWebServiceHandler(uri, marshaller);
</programlisting>
Either adapter can then be referenced from a <classname>HandlerEndpoint</classname> that is subscribed to a
<interfacename>MessageChannel</interfacename>. The endpoint is then responsible for passing the response to the
proper reply channel. It will first check for an "output-channel" on the endpoint itself and will fallback to a
<emphasis>returnAddress</emphasis> on the original message's header.
Either adapter can then be referenced from a <classname>service-activator</classname> element
that is subscribed to an input-channel. The endpoint is then responsible for passing the response to the
proper reply channel. It will first check for an "output-channel" on the service-activator and will
fallback to a <emphasis>returnAddress</emphasis> on the original message's header.
</para>
<para>
For more detail on the inner workings, see the Spring Web Services reference guide's chapter covering
@@ -211,7 +220,7 @@ marshallingAdapter = new MarshallingWebServiceTargetAdapter(uri, marshaller);
<para>
Spring Integration also provides adapters for streams. Both <classname>ByteStreamSource</classname> and
<classname>CharacterStreamSource</classname> implement the <interfacename>Source</interfacename> interface. By
configuring one of these within a <classname>SourceEndpoint</classname>, the polling period can be configured,
configuring one of these within a channel-adapter element, the polling period can be configured,
and the Message Bus can automatically detect and schedule them. The byte stream version requires an
<classname>InputStream</classname>, and the character stream version requires a <classname>Reader</classname> as
the single constructor argument. The <classname>ByteStreamSource</classname> also accepts the 'bytesPerMessage'
@@ -222,8 +231,8 @@ marshallingAdapter = new MarshallingWebServiceTargetAdapter(uri, marshaller);
<classname>CharacterStreamTarget</classname>. Each requires a single constructor argument -
<classname>OutputStream</classname> for byte streams or <classname>Writer</classname> for character streams,
and each provides a second constructor that adds the optional 'bufferSize' property. Since both of these
ultimately implement the <interfacename>Target</interfacename> interface, they can be referenced from a
<classname>TargetEndpoint</classname> configuration as will be described in more detail in
ultimately implement the <interfacename>MessageTarget</interfacename> interface, they can be referenced from a
<emphasis>channel-adapter</emphasis> configuration as will be described in more detail in
<xref linkend="namespace-endpoint"/>.
</para>
</section>
@@ -233,7 +242,7 @@ marshallingAdapter = new MarshallingWebServiceTargetAdapter(uri, marshaller);
Spring <classname>ApplicationEvents</classname> can also be integrated as either a source or target for Spring
Integration message channels. To receive the events and send to a channel, simply define an instance of Spring
Integration's <classname>ApplicationEventSource</classname> (as with all source implementations, this can then
be configured within a <classname>SourceEndpoint</classname> and automatically detected by the message bus). The
be configured within a "channel-adapter" element and automatically detected by the message bus). The
<classname>ApplicationEventSource</classname> also implements Spring's <interfacename>ApplicationListener</interfacename>
interface. By default it will pass all received events as Spring Integration Messages. To limit based on the type
of event, configure the list of event types that you want to receive with the 'eventTypes' property.