To create a Message Channel instance, you can use the 'channel' element:
<channel id="exampleChannel"/>
The default channel type is Point to Point. To create a Publish Subscribe channel, use the "publish-subscribe-channel" element:
<publish-subscribe-channel id="exampleChannel"/>
To create a Datatype Channel that only
accepts messages containing a certain payload type, provide the fully-qualified class name in the
channel element's datatype
attribute:
<channel id="numberChannel" datatype="java.lang.Number"/>
Note that the type check passes for any type that is assignable to the channel's
datatype. In other words, the "numberChannel" above would accept messages whose payload is
java.lang.Integer
or java.lang.Double
. Multiple types can be
provided as a comma-delimited list:
<channel id="stringOrNumberChannel" datatype="java.lang.String,java.lang.Number"/>
When using the "channel" element without any sub-elements, it will create a DirectChannel
instance (a SubscribableChannel
).
However, you can alternatively provide a variety of "queue" sub-elements to create any of the pollable channel types (as described in Section 3.2, “Message Channel Implementations”). Examples of each are shown below.
As mentioned above, DirectChannel
is the default type.
<channel id="directChannel"/>
A default channel will have a round-robin load-balancer and will also have failover enabled (See the discussion in the section called “DirectChannel” for more detail). To disable one or both of these, add a <dispatcher/> sub-element and configure the attributes:
<channel id="failFastChannel"> <dispatcher failover="false"/> </channel> <channel id="channelWithFixedOrderSequenceFailover"> <dispatcher load-balancer="none"/> </channel>
To create a QueueChannel
, use the "queue" sub-element.
You may specify the channel's capacity:
<channel id="queueChannel"> <queue capacity="25"/> </channel>
Note | |
---|---|
If you do not provide a value for the 'capacity' attribute on this <queue/> sub-element, the resulting queue will be unbounded. To avoid issues such as OutOfMemoryErrors, it is highly recommended to set an explicit value for a bounded queue. |
To create a PublishSubscribeChannel
, use the "publish-subscribe-channel" element.
When using this element, you can also specify the "task-executor" used for publishing
Messages (if none is specified it simply publishes in the sender's thread):
<publish-subscribe-channel id="pubsubChannel" task-executor="someExecutor"/>
If you are providing a Resequencer or Aggregator downstream
from a PublishSubscribeChannel
, then you can set the 'apply-sequence' property
on the channel to true
. That will indicate that the channel should set the sequence-size
and sequence-number Message headers as well as the correlation id prior to passing the Messages along.
For example, if there are 5 subscribers, the sequence-size would be set to 5, and the Messages would
have sequence-number header values ranging from 1 to 5.
<publish-subscribe-channel id="pubsubChannel" apply-sequence="true"/>
Note | |
---|---|
The 'apply-sequence' value is false by default so that a Publish Subscribe Channel
can send the exact same Message instances to multiple outbound channels. Since Spring Integration
enforces immutability of the payload and header references, the channel creates new Message
instances with the same payload reference but different header values when the flag is set to
true .
|
To create an ExecutorChannel
, add the <dispatcher> sub-element along
with a 'task-executor' attribute. Its value can reference any TaskExecutor
within the context. For example, this enables configuration of a thread-pool for dispatching messages
to subscribed handlers. As mentioned above, this does break the "single-threaded" execution context
between sender and receiver so that any active transaction context will not be shared by the invocation
of the handler (i.e. the handler may throw an Exception, but the send invocation has already returned
successfully).
<channel id="executorChannel"> <dispatcher task-executor="someExecutor"/> </channel>
Note | |
---|---|
The "load-balancer" and "failover" options are also both available on the dispatcher sub-element
as described above in the section called “DirectChannel Configuration”. The same defaults
apply as well. So, the channel will have a round-robin load-balancing strategy with failover
enabled unless explicit configuration is provided for one or both of those attributes.
<channel id="executorChannelWithoutFailover"> <dispatcher task-executor="someExecutor" failover="false"/> </channel> |
To create a PriorityChannel
, use the "priority-queue" sub-element:
<channel id="priorityChannel"> <priority-queue capacity="20"/> </channel>
By default, the channel will consult the MessagePriority
header of the
message. However, a custom Comparator
reference may be
provided instead. Also, note that the PriorityChannel
(like the other types)
does support the "datatype" attribute. As with the QueueChannel, it also supports a "capacity" attribute.
The following example demonstrates all of these:
<channel id="priorityChannel" datatype="example.Widget"> <priority-queue comparator="widgetComparator" capacity="10"/> </channel>
A RendezvousChannel
is created when the queue sub-element is
a <rendezvous-queue>. It does not provide any additional configuration options to
those described above, and its queue does not accept any capacity value since it is a
0-capacity direct handoff queue.
<channel id="rendezvousChannel"/> <rendezvous-queue/> </channel>
The ThreadLocalChannel
does not provide any additional configuration options.
<thread-local-channel id="threadLocalChannel"/>
Message channels may also have interceptors as described in Section 3.3, “Channel Interceptors”. The
<interceptors> sub-element can be added within <channel> (or the more specific element
types). Provide the "ref" attribute to reference any Spring-managed object that implements the
ChannelInterceptor
interface:
<channel id="exampleChannel"> <interceptors> <ref bean="trafficMonitoringInterceptor"/> </interceptors> </channel>
In general, it is a good idea to define the interceptor implementations in a separate location since they usually provide common behavior that can be reused across multiple channels.
As mentioned above, Spring Integration provides a simple Wire Tap interceptor out of the box. You can configure a Wire Tap on any channel within an 'interceptors' element. This is especially useful for debugging, and can be used in conjunction with Spring Integration's logging Channel Adapter as follows:
<channel id="in"> <interceptors> <wire-tap channel="logger"/> </interceptors> </channel> <logging-channel-adapter id="logger" level="DEBUG"/>
Tip | |
---|---|
The 'logging-channel-adapter' also accepts a boolean attribute: 'log-full-message'. That is false by default so that only the payload is logged. Setting that to true enables logging of all headers in addition to the payload. |
Note | |
---|---|
If namespace support is enabled, there are also two special channels defined within the context by default:
|