Updating reference documentation for M5.

This commit is contained in:
Mark Fisher
2008-07-08 03:33:24 +00:00
parent a9e7146170
commit 08b56b3666
2 changed files with 175 additions and 249 deletions

View File

@@ -14,7 +14,9 @@
Object getId();
MessageHeader getHeader();
T getPayload();
void setPayload(T payload);
boolean isExpired();
void copyHeader(MessageHeader header, boolean overwriteExistingValues);
}</programlisting>
And the header provides the following properties:
<table id="api-message-headerproperties">
@@ -75,8 +77,9 @@
new GenericMessage&lt;T&gt;(T payload);
new GenericMessage&lt;T&gt;(T payload, MessageHeader headerToCopy)</programlisting>
When no id is provided, a random unique id will be generated. The constructor that accepts a
<classname>MessageHeader</classname> will copy properties, attributes, and any 'returnAddress' from the
provided header. There are also two convenient subclasses available currently:
<classname>MessageHeader</classname> will copy properties and attributes as well as the
'returnAddress', 'sequenceNumber', and 'sequenceSize' properties from the provided header.
There are also two convenient subclasses available currently:
<classname>StringMessage</classname> and <classname>ErrorMessage</classname>. The latter accepts any
<classname>Throwable</classname> object as its payload.
</para>
@@ -103,11 +106,11 @@ new GenericMessage&lt;T&gt;(T payload, MessageHeader headerToCopy)</programlisti
</section>
<section id="api-source">
<title>Source</title>
<title>MessageSource</title>
<para>
The <interfacename>Source</interfacename> interface defines a single method for receiving
The <interfacename>MessageSource</interfacename> interface defines a single method for receiving
<interfacename>Message</interfacename> objects.
<programlisting language="java">public interface Source&lt;T&gt; {
<programlisting language="java">public interface MessageSource&lt;T&gt; {
Message&lt;T&gt; receive();
}</programlisting>
Spring Integration also provides a <classname>MethodInvokingSource</classname> implementation that serves as an
@@ -115,32 +118,32 @@ new GenericMessage&lt;T&gt;(T payload, MessageHeader headerToCopy)</programlisti
To use the <classname>MethodInvokingSource</classname>, provide the Object reference and the method name.
<programlisting language="java">MethodInvokingSource source = new MethodInvokingSource();
source.setObject(new SourceObject());
source.setMethod("sourceMethod");
source.setMethodName("sourceMethod");
Message&lt;?&gt; result = source.receive();</programlisting>
It is generally more common to configure a <classname>MethodInvokingSource</classname> in XML by providing a
bean reference.
<programlisting language="xml"><![CDATA[<source-adapter id="source" ref="sourceObject" method="sourceMethod"/>]]></programlisting>
bean reference in the "source" attribute of a &lt;channel-adapter&gt; element.
<programlisting language="xml"><![CDATA[<channel-adapter source="sourceObject" method="sourceMethod" channel="someChannel"/>]]></programlisting>
</para>
</section>
<section id="api-target">
<title>Target</title>
<title>MessageTarget</title>
<para>
The <interfacename>Target</interfacename> interface defines a single method for sending
The <interfacename>MessageTarget</interfacename> interface defines a single method for sending
<interfacename>Message</interfacename> objects.
<programlisting language="java">public interface Target {
<programlisting language="java">public interface MessageTarget {
boolean send(Message&lt;?&gt; message);
}</programlisting>
As with the <interfacename>Source</interfacename>, Spring Integration also provides a
As with the <interfacename>MessageSource</interfacename>, Spring Integration also provides a
<classname>MethodInvokingTarget</classname> adapter class.
<programlisting language="java">MethodInvokingTarget target = new MethodInvokingTarget();
target.setObject(new TargetObject());
target.setMethodName("targetMethod");
target.afterPropertiesSet();
target.send(new StringMessage("test"));</programlisting>
Likewise, the corresponding XML configuration is very similar to that of
<classname>MethodInvokingSource</classname>.
<programlisting language="xml"><![CDATA[<target-adapter id="target" ref="targetObject" method="targetMethod"/>]]></programlisting>
When creating a Channel Adapter for this target, the corresponding XML configuration
is very similar to that of <classname>MethodInvokingSource</classname>.
<programlisting language="xml"><![CDATA[<channel-adapter channel="someChannel" target="targetObject" method="targetMethod"/>]]></programlisting>
</para>
</section>
@@ -153,7 +156,6 @@ target.send(new StringMessage("test"));</programlisting>
<programlisting language="java"><![CDATA[public interface MessageChannel {
String getName();
void setName(String name);
DispatcherPolicy getDispatcherPolicy();
boolean send(Message message);
boolean send(Message message, long timeout);
Message receive();
@@ -169,10 +171,28 @@ target.send(new StringMessage("test"));</programlisting>
Spring Integration provides several different implementations of the
<interfacename>MessageChannel</interfacename> interface. Each is briefly described in the sections below.
</para>
<section id="api-messagechannel-publishsubscribechannel">
<title>PublishSubscribeChannel</title>
<para>
The <classname>PublishSubscribeChannel</classname> implementation broadcasts any Message
sent to it to all of its subscribed consumers. This is most often used for sending
<emphasis>Event Messages</emphasis> whose primary role is notification as opposed to
<emphasis>Document Messages</emphasis> which are generally intended to be processed by
a single consumer. Note that the <classname>PublishSubscribeChannel</classname> is
intended for sending only. Since it broadcasts to its subscribers directly when its
<methodname>send(Message)</methodname> method is invoked, consumers cannot receive
Messages by invoking <methodname>receive()</methodname>. Instead, any subscriber must
be a <interfacename>MessageTarget</interfacename> itself, and the subscriber's
<methodname>send(Message)</methodname> method will be invoked in turn.
</para>
</section>
<section id="api-messagechannel-queuechannel">
<title>QueueChannel</title>
<para>
The <classname>QueueChannel</classname> implementation wraps a queue. It provides a no-argument constructor
The <classname>QueueChannel</classname> implementation wraps a queue. Unlike, the
<classname>PublishSubscribeChannel</classname>, the <classname>QueueChannel</classname> has
point-to-point semantics. In other words, even if the channel has multiple consumers, only
one of them should receive any Message sent to that channel. It provides a no-argument constructor
(that uses a default capacity of 100) as well as a constructor that accepts the queue capacity:
<programlisting language="java">public QueueChannel(int capacity)</programlisting>
A channel that has not reached its capacity limit will store messages in its internal queue, and the
@@ -219,14 +239,17 @@ target.send(new StringMessage("test"));</programlisting>
<section id="api-messagechannel-directchannel">
<title>DirectChannel</title>
<para>
The <classname>DirectChannel</classname> is significantly different than the channel implementations described
thus far. It's primary purpose is to enable a single thread to perform the operations on "both sides" of the
channel. For example, if a <classname>HandlerEndpoint</classname> is subscribed to a
<classname>DirectChannel</classname>, then sending a Message to that channel will trigger invocation of the
handler <emphasis>directly in the sender's thread</emphasis>. The key motivation for providing a channel
implementation with this behavior is to support transactions. If the send call is invoked within the scope of a
transaction, then the outcome of the handler invocation can play a role in determining the ultimate result of
that transaction (commit or rollback).
The <classname>DirectChannel</classname> has point-to-point semantics, but otherwise is more similar
to the <classname>PublishSubscribeChannel</classname> than any of the queue-based channel implementations
described above. In other words, it also dispatches Messages directly but only to a single receiver. Its
primary purpose is to enable a single thread to perform the operations on "both sides" of the channel. For
example, if a receiving target is subscribed to a <classname>DirectChannel</classname>, then sending a
Message to that channel will trigger invocation of that target's <methodname>send(Message)</methodname>
method <emphasis>directly in the sender's thread</emphasis>. The key motivation for providing a channel
implementation with this behavior is to support transactions that must span across the channel while still
benefiting from the abstraction and loose coupling that the channel provides. If the send call is invoked
within the scope of a transaction, then the outcome of the target's invocation can play a role in determining
the ultimate result of that transaction (commit or rollback).
</para>
</section>
<section id="api-messagechannel-threadlocalchannel">
@@ -307,155 +330,59 @@ target.send(new StringMessage("test"));</programlisting>
<interfacename>Message</interfacename>, but how do the messages get passed from the channel to the handler?
As mentioned earlier, the <classname>MessageBus</classname> provides a runtime form of inversion of control, and
one of the primary responsibilities that it assumes is connecting the channels to the handlers. It also connects
Sources and Targets to channels, and it manages the scheduling of pollers and dispatchers.
MessageSources and MessageTargets to channels, and it manages the scheduling of pollers and dispatchers.
</para>
<para>
The <interfacename>MessageBus</interfacename> is an example of a mediator. It performs a number of roles - mostly
by delegating to other strategies. One of its main responsibilities is to manage registration of the
<interfacename>MessageChannels</interfacename> and <interfacename>MessageHandlers</interfacename>. It provides
the following methods:
<programlisting language="java">public void registerChannel(String name, MessageChannel channel)
<interfacename>MessageChannels</interfacename> and endpoints, such as <emphasis>Channel Adapters</emphasis>
and <emphasis>Service Activators</emphasis>. It recognizes any of these instances that have been defined
within its <interfacename>ApplicationContext</interfacename>.
</para>
<para>
The message bus handles several of the concerns so that the channels, sources, targets, and Message-handling
objects can be as simple as possible. These responsibilities include the lifecycle management of
message endpoints, the activation of subscriptions, and the scheduling of dispatchers (including
the configuration of thread pools). The bus coordinates all of that behavior based upon the metadata provided
in bean definitions. Furthermore, those bean definitions may be provided via XML and/or annotations
(we will look at examples of both configuration options shortly).
</para>
<para>
The bus creates and schedules triggers for all of its registered endpoints. When an endpoint
receives a trigger event, it will poll the <interfacename>MessageSource</interfacename> that
was provided in its metadata. For example, a <emphasis>Channel Adapter</emphasis> will poll the
referenced "source", and a <emphasis>Service Activator</emphasis> will poll the referenced
"input-channel".
</para>
</section>
public void registerHandler(String name, MessageHandler handler,
Subscription subscription)
public void registerHandler(String name, MessageHandler handler,
Subscription subscription,
ConcurrencyPolicy concurrencyPolicy)</programlisting>
As those method signatures reveal, the message bus is handling several of the concerns here so that the channel
and handler objects can be as simple as possible. These responsibilities include the creation and lifecycle
management of message dispatchers, the activation of handler subscriptions, and the configuration of thread
pools. The bus coordinates all of that behavior based upon the metadata provided via these registration methods,
and typically developers will not even use this API directly since the metadata can be provided in XML and/or
annotations. We will briefly take a look at each of those metadata objects.
<section id="api-messageendpoint">
<title>MessageEndpoint</title>
<para>
As described in <xref linkend="overview"/>, there are different types of Message Endpoint, such
as the <emphasis>Channel Adapter</emphasis> (inbound or outbound) and the <emphasis>Service Activator</emphasis>.
Spring Integration provides many other components that are also endpoints, such as Routers,
Splitters, and Aggregators. Each endpoint may provide its own specific metadata so that the
<classname>MessageBus</classname> can manage its connection to a channel and its polling schedule.
</para>
<para>
The bus creates and manages dispatchers that pull messages from a channel in order to push those messages to
handlers subscribed to that channel. Each channel has a <classname>DispatcherPolicy</classname> that contains
metadata for configuring those dispatchers:
<table id="api-messagebus-dispatcherpolicy">
<title>Properties of the DispatcherPolicy</title>
<tgroup cols="3">
<colspec align="left"/>
<thead>
<row>
<entry align="center">Property Name</entry>
<entry align="center">Default Value</entry>
<entry align="center">Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>publishSubscribe</entry>
<entry>false</entry>
<entry>whether the dispatcher should attempt to publish to all of its handlers (rather than just one)</entry>
</row>
<row>
<entry>maxMessagesPerTask</entry>
<entry>1</entry>
<entry>maximum number of messages to retrieve per poll</entry>
</row>
<row>
<entry>receiveTimeout</entry>
<entry>1000 (milliseconds)</entry>
<entry>how long to block on the receive call (0 for no blocking, -1 for indefinite block)</entry>
</row>
<row>
<entry>rejectionLimit</entry>
<entry>5</entry>
<entry>maximum number of attempts to invoke handlers (e.g. no threads available)</entry>
</row>
<row>
<entry>retryInterval</entry>
<entry>1000 (milliseconds)</entry>
<entry>amount of time to wait between successive attempts to invoke handlers</entry>
</row>
<row>
<entry>shouldFailOnRejectionLimit</entry>
<entry>true</entry>
<entry>whether to throw a <classname>MessageDeliveryException</classname> if the 'rejectionLimit' is
reached - if this is set to 'false', then such undeliverable messages would be dropped silently</entry>
</row>
</tbody>
</tgroup>
</table>
The scheduling metadata is provided as an implementation of the <interfacename>Schedule</interfacename> interface.
This is an abstraction designed to allow extensibility of schedulers for messaging tasks. Currently, there is a
single implementation named <classname>PollingSchedule</classname> and the endpoint may set the
<emphasis>period</emphasis> property. The polling period may differ depending on the type of MessageSource
(e.g. file-system vs. JMS).
</para>
<para>
The bus registers handlers with a channel's dispatcher based upon the <classname>Subscription</classname>
metadata provided to the <methodname>registerHandler()</methodname> method.
<table id="api-messagebus-subscription">
<title>Properties of the Subscription</title>
<tgroup cols="2">
<colspec align="left" />
<thead>
<row>
<entry align="center">Property Name</entry>
<entry align="center">Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>channel</entry>
<entry>the channel instance to subscribe to (an object reference)</entry>
</row>
<row>
<entry>channelName</entry>
<entry>the name of the channel to subscribe to - only used as a fallback if 'channel' is null</entry>
</row>
<row>
<entry>schedule</entry>
<entry>the scheduling metadata (see below)</entry>
</row>
</tbody>
</tgroup>
</table>
The scheduling metadata is provided as an implementation of the <interfacename>Schedule</interfacename>
interface. This is an abstraction designed to allow extensibility of schedulers for messaging tasks. Currently,
there is a single implementation named <classname>PollingSchedule</classname> that provides the following
properties:
<table id="api-messagebus-pollingschedule">
<title>Properties of the PollingSchedule</title>
<tgroup cols="3">
<colspec align="left"/>
<thead>
<row>
<entry align="center">Property Name</entry>
<entry align="center">Default Value</entry>
<entry align="center">Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>period</entry>
<entry>N/A</entry>
<entry>the delay interval between each poll</entry>
</row>
<row>
<entry>initialDelay</entry>
<entry>0</entry>
<entry>the delay prior to the first poll</entry>
</row>
<row>
<entry>timeUnit</entry>
<entry>TimeUnit.MILLISECONDS</entry>
<entry>time unit for 'period' and 'initialDelay'</entry>
</row>
<row>
<entry>fixedRate</entry>
<entry>false</entry>
<entry>'false' indicates fixed-delay (no backlog)</entry>
</row>
</tbody>
</tgroup>
</table>
The <classname>PollingSchedule</classname> constructor requires the 'period' value.
</para>
<para>
The <classname>ConcurrencyPolicy</classname> is an optional parameter to provide when registering a handler.
When the <interfacename>MessageBus</interfacename> registers a handler, it will use these properties to configure
that handler's thread pool. These parameters are configurable on a per-handler basis since handlers may have
different performance characteristics and may have different expectations with regard to the volume of
throughput. The following table lists the available properties and their default values:
While the MessageBus manages the scheduling of the trigger invocation threads, it may be necessary
to have concurrent threads for the endpoint's processing of each receive-and-handle unit of work.
Spring Integration provides an endpoint interceptor called <classname>ConcurrencyInterceptor</classname>
for this very purpose. The interceptor's configuration is provided by the
<classname>ConcurrencyPolicy</classname> metadata object. When the <interfacename>MessageBus</interfacename>
activates an endpoint that has been defined with a ConcurrencyInterceptor, it will use these properties to
configure that endpoint's thread pool. These interceptors are configurable on a per-endpoint basis since
different endpoint handlers may have different performance characteristics and may have different
expectations with regard to the volume of throughput. The following table lists the available properties
of the <classname>ConcurrencyPolicy</classname> and their default values:
<table id="api-messagebus-concurrencypolicy">
<title>Properties of the ConcurrencyPolicy</title>
<tgroup cols="3">
@@ -492,49 +419,28 @@ public void registerHandler(String name, MessageHandler handler,
</tgroup>
</table>
</para>
</section>
<section id="api-messageendpoint">
<title>MessageEndpoint</title>
<para>
As described in <xref linkend="overview"/>, there are three implementations of the
<interfacename>MessageEndpoint</interfacename> interface: <classname>SourceEndpoint</classname>,
<classname>TargetEndpoint</classname>, and <classname>HandlerEndpoint</classname>. These endpoints provide the
metadata necessary for the <classname>MessageBus</classname> to manage <interfacename>Sources</interfacename>,
<interfacename>Targets</interfacename>, and <interfacename>MessageHandlers</interfacename> respectively.
</para>
<para>
For a <interfacename>SourceEndpoint</interfacename>, the <classname>MessageBus</classname> schedules a task for
polling the <interfacename>Source</interfacename> based on the provided schedule.
</para>
<para>
When a <interfacename>Target</interfacename> or <interfacename>MessageHandler</interfacename> is registered with
the <classname>MessageBus</classname>, the bus assigns it to a dispatcher that polls a
<interfacename>MessageChannel</interfacename> based on the provided schedule. Targets and handlers may also
provide concurrency settings in which case a thread pool will be created for asynchronous processing of messages.
</para>
<para>
Rather than programming to the API directly, it is simpler and more common to register sources, targets, and
handlers with either XML or annotation-based metadata. Then, the message endpoint is an internal responsibility
of the bus. The configuration options are discussed in detail in <xref linkend="namespace-endpoint"/>.
The details of configuring this and other metadata for each endpoint will be discussed in detail in
<xref linkend="namespace-endpoint"/>.
</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.
As described above, each endpoint is registered with the message bus and is thereby subscribed
to a channel. Often it is necessary to provide additional <emphasis>dynamic</emphasis> logic to
determine what messages the endpoint should receive. The <interfacename>MessageSelector</interfacename>
strategy interface fulfills that role.
<programlisting language="java"><![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.
A <interfacename>MessageEndpoint</interfacename> can be configured with a selector (or selector-chain)
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 language="java"><![CDATA[PayloadTypeSelector selector = new PayloadTypeSelector(String.class, Integer.class);
assertTrue(selector.accept(new StringMessage("example")));
assertTrue(selector.accept(new GenericMessage<Integer>(123)));
@@ -549,7 +455,7 @@ assertFalse(selector.accept(new GenericMessage<SomeObject>(someObject)));
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 language="java">channel.purge(someSelector);</programlisting>
There is even a <classname>ChannelPurger</classname> utility class whose purge operation is a good candidate for
There is a <classname>ChannelPurger</classname> utility class whose purge operation is a good candidate for
Spring's JMX support:
<programlisting language="java">ChannelPurger purger = new ChannelPurger(new ExampleMessageSelector(), channel);
purger.purge();</programlisting>

View File

@@ -120,44 +120,50 @@
</mediaobject>
To facilitate the conversion of Objects to Messages, Spring Integration also defines a strategy interface
for creating Messages called <interfacename>MessageCreator</interfacename>. While it is relatively easy to
implement Source directly, an adapter is also available for invoking arbitrary methods on plain Objects. Also,
several Source implementations are already available within the Spring Integration Adapters module. For a
detailed discussion of the various adapters, see <xref linkend="adapters"/>.
implement Spring Integration's <interfacename>MessageSource</interfacename> interface directly, an adapter
is also available for invoking arbitrary methods on plain Objects. Also, several
<interfacename>MessageSource</interfacename> implementations are already available within the Spring
Integration Adapters module. For a detailed discussion of the various adapters, see <xref linkend="adapters"/>.
</para>
</section>
<section>
<title>Message Target</title>
<para>
Just as a Source enables Message reception, a Target handles the responsibility of sending Messages. As with
a Source, a Target can act as an adapter that converts Messages into the Objects expected by some other system.
Just as a <interfacename>MessageSource</interfacename> enables Message reception, a
<interfacename>MessageTarget</interfacename> handles the responsibility of sending Messages. As with the
<interfacename>MessageSource</interfacename>, a <interfacename>MessageTarget</interfacename> can act as an
adapter that converts Messages into the Objects expected by some other system.
<mediaobject>
<imageobject>
<imagedata align="center" fileref="images/target.png" format="PNG"/>
</imageobject>
</mediaobject>
Spring Integration provides a strategy interface for mapping Messages to Objects called
<interfacename>MessaegMapper</interfacename>. The Target interface may be implemented directly, but an adapter
is also available for invoking arbitrary methods on plain Objects (delegating to the Message-mapping strategy
in the process). As with Sources, several Target implementations are already available within the Spring
Integration Adapters module as discussed in <xref linkend="adapters"/>.
<interfacename>MessageMapper</interfacename>. The MessageTarget interface may be implemented directly, but
an adapter is also available for invoking arbitrary methods on plain Objects (delegating to a
<interfacename>MessageMapper</interfacename> strategy in the process). As with MessageSources, several
MessageTarget implementations are already available within the Spring Integration Adapters module as
discussed in <xref linkend="adapters"/>.
</para>
</section>
<section id="overview-components-handler">
<title>Message Handler</title>
<para>
As described above, the Source and Target components support conversion between Objects and Messages so that
application code and/or external systems can be connected to a Spring Integration application rather easily.
However, both Source and Target are unidirectional while the application code or external system to be invoked
may provide a return value. The Message Handler interface supports these request-reply scenarios.
As described above, the MessageSource and MessageTarget components support conversion between Objects and
Messages so that application code and/or external systems can be connected to a Spring Integration application
rather easily. However, both MessageSource and MessageTarget are unidirectional while the application code or
external system to be invoked may provide a return value. The <interfacename>MessageHandler</interfacename>
interface supports these request-reply scenarios.
<mediaobject>
<imageobject>
<imagedata align="center" fileref="images/handler.png" format="PNG"/>
</imageobject>
</mediaobject>
As with the Source and Target, Spring Integration also provides an adapter that itself implements the Message
Handler interface while supporting the invocation of arbitrary methods on plain Objects. The adapter relies
upon the message-creating and message-mapping strategies to handle the bidirectional Object/Message conversion.
For more information about the Message Handler, see <xref linkend="api-messagehandler"/>.
As with the MessageSource and MessageTarget, Spring Integration also provides an adapter that itself implements
the <interfacename>MessageHandler</interfacename> interface while supporting the invocation of arbitrary methods
on plain Objects. The adapter relies upon the message-creating and message-mapping strategies to handle the
bidirectional Object/Message conversion. For more information about the Message Handler, see
<xref linkend="api-messagehandler"/>.
</para>
</section>
<section id="overview-components-channel">
@@ -165,27 +171,27 @@
<para>
A Message Channel represents the "pipe" of a pipes-and-filters architecture. Producers send Messages to
a channel, and consumers receive Messages from a channel. By providing both send and receive operations, a
Message Channel basically combines the roles of Source and Target.
Message Channel basically combines the roles of MessageSource and MessageTarget.
<mediaobject>
<imageobject>
<imagedata align="center" fileref="images/channel.png" format="PNG"/>
</imageobject>
</mediaobject>
Spring Integration provides a number of different channel implementations: QueueChannel, PriorityChannel,
RendezvousChannel, DirectChannel, and ThreadLocalChannel. These are described in detail in
<xref linkend="api-messagechannel"/>.
Spring Integration provides a number of different channel implementations: PublishSubscribeChannel,
QueueChannel, PriorityChannel, RendezvousChannel, DirectChannel, and ThreadLocalChannel. These are described
in detail in <xref linkend="api-messagechannel"/>.
</para>
</section>
<section id="overview-components-endpoint">
<title>Message Endpoint</title>
<para>
Thus far, the component diagrams show Consumers, Producers, and Requesters invoking the Source, Target, and
Message Handlers respectively. However, one of the primary goals of Spring Integration is to simplify the
development of enterprise integration solutions through <emphasis>inversion of control</emphasis>. This means
that you should not have to implement such Producers, Consumers, and Requesters directly. Instead, you should
be able to focus on your domain logic with an implementation based on plain Objects. Then, by providing
declarative configuration, you can "connect" your application code to the messaging infrastructure provided by
Spring Integration. The components responsible for these connections are Message Endpoints.
Thus far, the component diagrams show consumers, producers, and requesters invoking the MessageSource,
MessageTarget, and MessageHandlers respectively. However, one of the primary goals of Spring Integration is to
simplify the development of enterprise integration solutions through <emphasis>inversion of control</emphasis>.
This means that you should not have to implement such consumers, producers, and requesters directly. Instead,
you should be able to focus on your domain logic with an implementation based on plain Objects. Then, by
providing declarative configuration, you can "connect" your application code to the messaging infrastructure
provided by Spring Integration. The components responsible for these connections are Message Endpoints.
</para>
<para>
A Message Endpoint represents the "filter" of a pipes-and-filters architecture. As mentioned above, the
@@ -194,47 +200,60 @@
the Message Channels. This is similar to the role of a Controller in the MVC paradigm. Just as a Controller
handles HTTP requests, the Message Endpoint handles Messages. Just as Controllers are mapped to URL patterns,
Message Endpoints are mapped to Message Channels. The goal is the same in both cases: isolate application code
from the infrastructure. Spring Integration provides three types of endpoints - one for each of the component
types described above: Source Endpoint, Target Endpoint, and Handler Endpoint.
from the infrastructure. Spring Integration provides Message Endpoints for connecting each of the component
types described above.
</para>
<section>
<title>Source Endpoint</title>
<title>Channel Adapter</title>
<para>
A Source Endpoint connects any Source implementation to a Message Channel. The invocation of the Source's
receive operation is controlled by scheduling information provided within the Source Endpoint's
configuration. Any time the receive operation returns a non-null Message, it is sent to the channel.
A Channel Adapter is an endpoint that connects either a MessageSource or a MessageTarget to a
MessageChannel. If a MessageSource is being adapted, then the adapter is responsible for receiving
Messages from the MessageSource and sending them to the MessageChannel. If a Message Target is being
adapted, then the adapter is responsible for receiving Messages from the MessageChannel and sending
them to the MessageTarget.
</para>
<para>
When a Channel Adapter is used to connect a MessageSource implementation to a Message Channel,
the invocation of the MessageSource's receive operation may be controlled by scheduling information
provided within the Channel Adapter's configuration. Any time the receive operation returns a non-null
Message, it is sent to the MessageChannel.
<mediaobject>
<imageobject>
<imagedata align="center" fileref="images/source-endpoint.png" format="PNG"/>
</imageobject>
<caption>An inbound "Channel Adapter" endpoint connects a MessageSource to a MessageChannel</caption>
</mediaobject>
</para>
</section>
<section>
<title>Target Endpoint</title>
<para>
A Target Endpoint connects a Message Channel to any Target implementation. The invocation of the Message
Channel's receive operation is controlled by scheduling information provided within the Target Endpoint's
configuration. Any time a non-null Message is received from the channel, it is sent to the Target.
When a Channel Adapter is used to connect a MessageTarget implementation to a Message Channel,
the invocation of the MessageChannel's receive operation may be controlled by scheduling information
provided within the Channel Adapter's configuration. Any time a non-null Message is received from the
MessageChannel, it is sent to the MessageTarget.
<mediaobject>
<imageobject>
<imagedata align="center" fileref="images/target-endpoint.png" format="PNG"/>
</imageobject>
<caption>An outbound "Channel Adapter" endpoint connects a MessageChannel to a MessageTarget</caption>
</mediaobject>
</para>
</section>
<section>
<title>Handler Endpoint</title>
<title>Service Activator</title>
<para>
Since Message Handler's are capable of returning reply Messages, the Handler Endpoint has some additional
responsibilities. The general behavior is the same as the Target Endpoint, but the Handler Endpoint must
make a distinction between "input-channel" and "output-channel". Whenever the Message Handler does return
a reply Message, that Message is sent to the output channel. If no output channel has been configured, then
the reply will be sent to the channel specified as the Message header's "return address" if available.
When the Object to be invoked is capable of returning a value, another type of endpoint is
needed to accommodate the additional responsibilities of the <emphasis>request/reply</emphasis>
interaction. The general behavior is similar to a Channel Adapter, but this type of endpoint -
the Service Activator - must make a distinction between the "input-channel" and the "output-channel".
Whenever the Message-handling Object does return a reply Message, that Message is sent to the output
channel. If no output channel has been configured, then the reply will be sent to the channel
specified in the MessageHeader's "return address" if available.
<mediaobject>
<imageobject>
<imagedata align="center" fileref="images/handler-endpoint.png" format="PNG"/>
</imageobject>
<caption>
A request-reply "Service Activator" endpoint connects a MessageHandler to input and output MessageChannels.
</caption>
</mediaobject>
</para>
</section>
@@ -242,10 +261,11 @@
<section id="overview-component-router">
<title>Message Router</title>
<para>
A Message Router is a particular type of <interfacename>MessageHandler</interfacename> that is capable of
receiving a Message and then deciding what channel or channels should receive the Message next. Typically the
decision is based upon the Message's content and/or metadata. A Message Router is often used as a dynamic
alternative to configuring the input and output channels for an endpoint.
A Message Router is a particular type of Message Endpoint that is capable of receiving a Message from
a MessageChannel and then deciding what channel or channels should receive the Message next (if any).
Typically the decision is based upon the Message's content and/or metadata available in the MessageHeader.
A Message Router is often used as a dynamic alternative to a statically configured output channel on
a Service Activator or other Message-handling endpoint.
<mediaobject>
<imageobject>
<imagedata align="center" fileref="images/router.png" format="PNG"/>