diff --git a/spring-integration-reference/src/configuration.xml b/spring-integration-reference/src/configuration.xml
index f1bbe7f7b1..495845d42a 100644
--- a/spring-integration-reference/src/configuration.xml
+++ b/spring-integration-reference/src/configuration.xml
@@ -83,7 +83,8 @@
When using the "channel" element, the creation of the channel instances will be deferred to the ChannelFactory
- defined on the MessageBus (see below).
+ bean whose name is "channelFactory" if defined within the ApplicationContext. If no such bean is defined, the default factory will
+ be used. The default implementation is QueueChannelFactory.
It is also possible to use more specific elements for the various channel types (as described in
@@ -102,7 +103,7 @@
The <publish-subscribe-channel/> element
To create a PublishSubscribeChannel, use the "publish-subscribe-channel" element.
- By using this element, you can also specify the "task-executor" used for publishing
+ 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="exampleChannel" task-executor="someTaskExecutor"/>
@@ -112,8 +113,8 @@
To create a PriorityChannel, use the "priority-channel" element:
]]>
- By default, the channel will consult the MessagePriority value in the
- message's header. However, a custom Comparator reference may be
+ 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 "queue-channel", it also supports a "capacity" attribute.
The following example demonstrates all of these:
@@ -168,15 +169,25 @@
A "channel-adapter" element can connect any implementation of the MessageSource
interface to a MessageChannel. When the MessageBus
- registers the endpoint, it will activate the subscription by assigning the endpoint to the input channel's dispatcher.
- The dispatcher is capable of handling multiple endpoint subscriptions for its channel and delegates to a scheduler
- for managing the tasks that pull messages from the source and push them to the channel. To configure the polling
- period for an individual channel-adapter's schedule, provide a 'schedule' sub-element with the 'period' in
- milliseconds:
-
-
+ registers the endpoint, it will activate the subscription and if necessary create a poller for the endpoint.
+ The Message Bus delegates to a TaskScheduler 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:
+
+
+
+
+
+
]]>
+
+
+ Cron support does require the Quartz JAR and its transitive dependencies. Also, keep in mind that pollers only
+ apply for PollableChannel implementations. On the other hand, subscribable channels
+ (PublishSubscribeChannel and DirectChannel) will send Messages to their subscribed targets directly.
+
+
The outbound <channel-adapter/> with a MessageTarget
@@ -184,19 +195,11 @@
A "channel-adapter" element can also connect a MessageChannel to any implementation
of the MessageTarget interface.
]]>
- Again, it is possible to provide a schedule:
+ Again, it is possible to provide a poller:
- ]]>]]>]]>]]>
-
-
- Individual endpoint schedules only apply for "Point-to-Point" channels, since in that case only a single
- subscriber needs to receive the message. On the other hand, when a Spring Integration channel is configured as
- a "Publish-Subscribe" channel, then the dispatcher will drive all endpoint notifications according to its own
- default schedule, and any 'schedule' element configured for those endpoints will be ignored.
-
-
The <service-activator/> element
@@ -214,21 +217,15 @@
In either case (MessageHandler 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 an "output-channel" was provided in the
- endpoint configuration:
+ channel. To determine the reply channel, it will first check if the NEXT_TARGET header contains
+ a non-null value, next it will check if an "output-channel" was provided in the endpoint configuration:
<service-activator input-channel="exampleChannel" output-channel="replyChannel"
ref="somePojo" method="someMethod"/>
- If no "output-channel" is available, it will next check the message header's 'returnAddress'
- property. If that value is available, it will then check its type. If it is a MessageChannel,
- the reply message will be sent to that channel. If it is a String, then the endpoint will
+ If no "output-channel" is available, it will finally check the message header's RETURN_ADDRESS
+ property. If that value is available, it will then check its type. If it is a MessageTarget,
+ the reply message will be sent to that target. If it is a String, then the endpoint will
attempt to resolve the channel by performing a lookup in the ChannelRegistry.
-
-
- To reverse the order so that the 'returnAddress' is given priority over the endpoint's "output-channel", then
- provide the "return-address-overrides" attribute with a value of 'true':
- <service-activator input-channel="exampleChannel" output-channel="replyChannel"
- ref="somePojo" method="someMethod" return-address-overrides="true"/>
- If neither is available, then a MessageHandlingException will be thrown.
+ If the target cannot be resolved, then a MessageHandlingException will be thrown.
@@ -244,11 +241,12 @@
EndpointInterceptors. The interface is defined as follows:
message);
+ Message> preHandle(Message> requestMessage);
- boolean aroundSend(Message> message, MessageTarget endpoint);
+ Message> aroundHandle(Message> requestMessage, MessageHandler handler);
+
+ Message> postHandle(Message> replyMessage);
- void postSend(Message> message, boolean result);
}]]>
There is also an EndpointInterceptorAdapter that provides no-op methods for convenience
when subclassing. Within an endpoint configuration, interceptors can be added within
@@ -258,7 +256,7 @@
ref="someObject"
method="someMethod"
output-channel="replyChannel">
-
+
@@ -266,61 +264,45 @@
]]>
- Spring Integration provides a TransactionInterceptor and namespace
- support with the <transaction-interceptor> element. The attributes for this element
- should be familiar to anyone who has experience with Spring's Transaction management:
+ 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:
-
-
-
-
+
+
+
]]>
- Spring Integration also provides a ConcurrencyInterceptor. By applying this, an endpoint becomes capable of
- managing a thread pool, and the concurrency settings you provide for that pool's core size, max size,
- and queue capacity 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
- target 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 'concurrency-interceptor' element within the 'interceptors' sub-element
- and then provide one or more of the properties shown below:
+ Spring Integration also provides support for executing the pollers with a
+ TaskExceutor. 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:
-
- ]]>]]>
-]]>
- Recall the default concurrency policy values as listed in .
- If no concurrency settings are provided (i.e. a null
- ConcurrencyPolicy), the endpoint's handler or target will be invoked in the caller's thread.
- Note that the "caller" is usually the dispatcher except in the case of a DirectChannel
- (see for more detail).
+
+
+
+]]>
+ 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 TaskExecutor interface.
-
- Another option for the concurrency-interceptor is to provide the "task-executor" attribute
- with a reference to any implementation of Spring's TaskExecutor
- interface.
-
-
-
- For the concurrency settings, the default queue capacity of 0 triggers the creation of a
- SynchronousQueue. In many cases, this is preferable since the direct handoff eliminates
- the chance of a message handling task being "stuck" in the queue (thread pool executors will favor adding to the
- queue rather than increasing the pool size). Specifically, whenever a dispatcher for a Point-to-Point channel
- has more than one subscribed endpoint, a task that is rejected due to an exhausted thread pool can be handled
- immediately by another endpoint whose pool has one or more threads available. On the other hand, when a
- particular channel/endpoint may be expecting bursts of activity, setting a queue capacity value might be the
- best way to accommodate the volume.
-
-
The Message Bus provides default error handling for its components in the form of a configurable error channel,
- and the 'message-bus' element accepts a reference with its 'error-channel' attribute:
-
+ and it will first check for a channel bean named 'errorChannel' within the context:
+
]]>
- When exceptions occur in a concurrent endpoint's execution of its MessageHandler
- callback, those exceptions will be wrapped in ErrorMessages and sent to the Message Bus'
- 'errorChannel' by default. To enable global error handling, simply register a handler on that channel. For
- example, you can configure Spring Integration's RootCauseErrorMessageRouter 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 Exception type. However, since most of the errors will already
- have been wrapped in MessageDeliveryException or MessageHandlingException,
+ When exceptions occur in a scheduled poller task's execution, those exceptions will be wrapped in
+ ErrorMessages 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
+ RootCauseErrorMessageRouter 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
+ Exception type. However, since most of the errors will already have been wrapped in
+ MessageDeliveryException or MessageHandlingException,
the RootCauseErrorMessageRouter is typically a better option.
@@ -356,28 +338,23 @@
]]>
- Another configurable property is the size of the dispatcher thread pool. The dispatcher threads are responsible
- for polling channels and then passing the messages to handlers.
+ 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.
]]>
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 concurrency
- policy is provided to an endpoint, then it will be invoked in the dispatcher's thread (with the exception of
- DirectChannels).
-
-
- Also, the Message Bus is capable of automatically creating channel instances if an endpoint registers a
- subscription by providing the name of a channel that the bus does not recognize.
- ]]>
+ 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).
- Finally, the type of channel that gets created automatically by the bus can be customized by using the
- "channel-factory" attribute on the "message-bus" definition as in the following example:
-
+ Finally, the type of channel that gets created automatically by the bus can be customized by defining a bean
+ that implements the ChannelFactory interface and whose name is "channelFactory".
+
-]]>
With this definition, all the channels created automatically will be PriorityChannel instances.
- Without the "channel-factory" element, the Message Bus will assume a default QueueChannelFactory.
+ Without a "channelFactory" bean, the Message Bus will assume a default QueueChannelFactory.