From 1edd57cf1838071a9e6fcc74e2ddacd462393d3d Mon Sep 17 00:00:00 2001 From: Mark Fisher Date: Wed, 20 Aug 2008 03:40:30 +0000 Subject: [PATCH] Updated the Message Channel, Message Endpoint, and Message Bus sections. --- .../src/configuration.xml | 189 ++++++++---------- 1 file changed, 83 insertions(+), 106 deletions(-) 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. - -
@@ -335,17 +317,17 @@ 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.