diff --git a/spring-integration-reference/src/namespaces.xml b/spring-integration-reference/src/namespaces.xml new file mode 100644 index 0000000000..65b5e584ee --- /dev/null +++ b/spring-integration-reference/src/namespaces.xml @@ -0,0 +1,568 @@ + + + + Configuration + +
+ Introduction + + Spring Integration offers a number of configuration options. Which option you choose depends upon your particular + needs and at what level you prefer to work. As with the Spring framework in general, it is also possible to mix + and match the various techniques according to the particular problem at hand. For example, you may choose the + XSD-based namespace for the majority of configuration combined with a handful of objects that are configured with + annotations. As much as possible, the two provide consistent naming. XML elements defined by the XSD schema will + match the names of annotations, and the attributes of those XML elements will match the names of annotation + properties. Direct usage of the API is of course always an option, but we expect that most users will choose one + of the higher-level options, or a combination of the namespace-based and annotation-driven configuration. + +
+ +
+ Namespace Support + + Spring Integration components can be configured with XML elements that map directly to the terminology and + concepts of enterprise integration. In many cases, the element names match those of the + Enterprise Integration Patterns. + + + To enable Spring Integration's namespace support within your Spring configuration files, add the following + namespace reference and schema mapping in your top-level 'beans' element: + xmlns:integration="http://www.springframework.org/schema/integration"http://www.springframework.org/schema/integration + http://www.springframework.org/schema/integration/spring-integration-1.0.xsd"> + + + You can choose any name after "xmlns:"; integration is used here for clarity, but you might + prefer a shorter abbreviation. Of course if you are using an XML-editor or IDE support, then the availability of + auto-completion may convince you to keep the longer name for clarity. Alternatively, you can create configuration + files that use the Spring Integration schema as the primary namespace: + <beans:beans xmlns="http://www.springframework.org/schema/integration"xmlns:beans="http://www.springframework.org/schema/beans"]]> + + + When using this alternative, no prefix is necessary for the Spring Integration elements. On the other hand, if + you want to define a generic Spring "bean" within the same configuration file, then a prefix would be required + for the bean element (<beans:bean ... />). Since it is generally a good idea to modularize the + configuration files themselves based on responsibility and/or architectural layer, you may find it appropriate to + use the latter approach in the integration-focused configuration files, since generic beans are seldom necessary + within those same files. For purposes of this documentation, we will assume the "integration" namespace is + primary. + + +
+ Configuring Message Channels + + To create a Message Channel instance, you can use the generic '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: + ]]> + 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: + ]]> + + + When using the "channel" element, the creation of the channel instances will be deferred to the ChannelFactory + 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 + ). Depending on the channel, these may provide additional configuration + options. Examples of each are shown below. + +
+ The <queue-channel/> element + + To create a QueueChannel, use the "queue-channel" element. + By using this element, you can also specify the channel's capacity: + <queue-channel id="exampleChannel" capacity="25"/> + +
+
+ The <publish-subscribe-channel/> element + + 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="exampleChannel" task-executor="someTaskExecutor"/> + +
+
+ The <priority-channel/> element + + To create a PriorityChannel, use the "priority-channel" element: + ]]> + 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: + +]]> + +
+
+ The <rendezvous-channel/> element + + The RendezvousChannel does not provide any additional configuration options. + ]]> + +
+
+ The <direct-channel/> element + + The DirectChannel does not provide any additional configuration options. + ]]> + +
+
+ The <thread-local-channel/> element + + The ThreadLocalChannel does not provide any additional configuration options. + ]]> + +
+ + Message channels may also have interceptors as described in . One or + more <interceptor> elements can be added as sub-elements of <channel> (or the more specific element + types). Provide the "ref" attribute to reference any Spring-managed object that implements the + ChannelInterceptor interface: + + ]]>]]>]]> + 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. + +
+ +
+ Configuring Message Endpoints + + Each of the endpoint types (channel-adapter, service-activator, etc) has its own element in the namespace. + +
+ The inbound <channel-adapter/> element with a MessageSource + + 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 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 + + A "channel-adapter" element can also connect a MessageChannel to any implementation + of the MessageTarget interface. + ]]> + Again, it is possible to provide a poller: + + ]]>]]>]]> + +
+
+ The <service-activator/> element + + To create a Service Activator, use the 'service-activator' element with the 'input-channel' and + 'ref' attributes: + <service-activator input-channel="exampleChannel" ref="exampleHandler"/> + + + The configuration above assumes that "exampleHandler" either contains a single method annotated with the + @ServiceActivator annotation or that it contains a single public method period. To delegate to an explicitlye + defined method of any object, simply add the "method" attribute. + <service-activator input-channel="exampleChannel" ref="somePojo" method="someMethod"/> + + + 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 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 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. + If the target cannot be resolved, then a MessageHandlingException will be thrown. + +
+ + Message Endpoints also support MessageSelectors. To configure a selector with + namespace support, simply add the "selector" attribute to the endpoint definition and reference an + implementation of the MessageSelector interface. + ]]> + + + Another important configuration option for message endpoints is the inclusion of + EndpointInterceptors. The interface is defined as follows: + preHandle(Message requestMessage); + + Message aroundHandle(Message requestMessage, MessageHandler handler); + + Message postHandle(Message replyMessage); + +}]]> + There is also an EndpointInterceptorAdapter that provides no-op methods for convenience + when subclassing. Within an endpoint configuration, interceptors can be added within + the <interceptors> sub-element. It accepts either "ref" elements or inner "beans": + + + + + + +]]> + + + 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 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: + + + + +]]> + 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. + +
+ +
+ Configuring the Message Bus + + The Message Bus plays a central role, but its configuration is quite simple since it is primarily concerned + with managing internal details based on the configuration of channels and endpoints. The bus is aware of its + host application context, and therefore is also capable of auto-detecting the channels and endpoints. + The Message Bus can be configured with a single empty element: + <message-bus/> + + + The Message Bus provides default error handling for its components in the form of a configurable error channel, + and it will first check for a channel bean named 'errorChannel' within the context: + + +]]> + 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. + + + The 'message-bus' element accepts several more optional attributes. First, you can control whether the + MessageBus will be started automatically (the default) or will require explicit startup + by invoking its start() method (MessageBus implements + Spring's Lifecycle interface): + ]]> + + + 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 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). + +
+ +
+ Configuring Adapters + + The most convenient way to configure Source and Target adapters is by using the namespace support. The + following examples demonstrate the namespace-based configuration of several source, target, gateway, + and handler adapters: + + + + + + + + + + + + + + +]]> + + + In the examples above, notice that simple implementations of the MessageSource + and MessageTarget interfaces do not accept any 'channel' references. To + connect such sources and targets to a channel, register them within a 'channel-adapter'. For example, here + is a File source with an endpoint whose polling will be scheduled to execute every 30 seconds by the + MessageBus. + + + + + +]]> + Likewise, here is an example of a JMS target that is registered within a 'channel-adapter' and whose Messages + will be received from the "exampleChannel" that is polled every 500 milliseconds. + + + + + +]]> + + + Any Channel Adapter can be created without a "channel" reference in which case it will implicitly create an + instance of DirectChannel. The created channel's name will match the "id" attribute + of the <channel-adapter/> element. Therefore, if the "channel" is not provided, the "id" is required. + +
+ +
+ Enabling Annotation-Driven Configuration + + The next section will describe Spring Integration's support for annotation-driven configuration. To enable + those features, add this single element to the XML-based configuration: + <annotation-driven/> + +
+
+ +
+ Annotations + + In addition to the XML namespace support for configuring Message Endpoints, it is also possible to use + annotations. The class-level @MessageEndpoint annotation indicates that the + annotated class is capable of being registered as an endpoint, and the method-level + @Handler annotation indicates that the annotated method is capable of handling + a message. + @MessageEndpoint(input="fooChannel") +public class FooService { + + @Handler + public void processMessage(Message message) { + ... + } +} + + + The @MessageEndpoint is not required. If you want to configure a POJO reference from the "ref" attribute + of a <service-activator/> element, it is sufficient to provide the @Handler method annotation. As long + as the "annotation-driven" support is enabled, a Spring-managed object with that method annotation (or the + others which are described below) will be post-processed such that it can be used as a reference from an + XML-configured endpoint. + + + In most cases, the annotated handler method should not require the Message type as its + parameter. Instead, the method parameter type can match the message's payload type. + public class FooService { + + @Handler + public void bar(Foo foo) { + ... + } + +} + + + When the method parameter should be mapped from a value in the MessageHeader, another + option is to use the parameter-level @Header annotation. + @MessageEndpoint(input="fooChannel") +public class FooService { + + @Handler + public void bar(@Header("foo") Foo foo) { + ... + } + +} + + + As described in the previous section, when the handler method returns a non-null value, the endpoint will + attempt to send a reply. This is consistent across both configuration options (namespace and annotations) in that + the the endpoint's output channel will be used if available, and the message header's RETURN_ADDRESS value will be + the fallback. To configure the output channel for an annotation-driven endpoint, provide the 'output' + attribute on the @MessageEndpoint. + @MessageEndpoint(input="exampleChannel", output="replyChannel") + + + Just as the 'poller' sub-element and its 'period' attribute can be provided for a namespace-based + endpoint, the @Poller annotation can be provided with the + @MessageEndpoint annotation. + @MessageEndpoint(input="exampleChannel") +@Poller(period=3000) +public class FooService { + ... +} + Likewise, @Concurrency provides an annotation-based equivalent of the + <pool-executor/> element: + @MessageEndpoint(input="fooChannel") +@Concurrency(coreSize=5, maxSize=20) +public class FooService { + + @Handler + public void bar(Foo foo) { + ... + } + +} + + + Several additional annotations are supported, and three of these act as a special form of handler method: + @Router, @Splitter and + @Aggregator. As with the @Handler annotation, + methods annotated with these annotations can either accept the Message itself, the + message payload, or a header value (with @Header) as the parameter. In fact, the method can accept a combination, + such as: + someMethod(String payload, @Header("x") int valueX, @Header("y") int valueY); + + + When using the @Router annotation, the annotated method can return either the + MessageChannel or String type. In the case of the latter, + the endpoint will resolve the channel name as it does for the default output. Additionally, the method can return + either a single value or a collection. When a collection is returned, the reply message will be sent to multiple + channels. To summarize, the following method signatures are all valid. + @Router +public MessageChannel route(Message message) {...} + +@Router +public List<MessageChannel> route(Message message) {...} + +@Router +public String route(Foo payload) {...} + +@Router +public List<String> route(Foo payload) {...} + + + In addition to payload-based routing, a common requirement is to route based on metadata available within the + message header as either a property or attribute. Rather than requiring use of the + Message type as the method parameter, the @Router + annotation may also use the same @Header parameter annotation that was introduced above. + @Router +public List<String> route(@Header("orderStatus") OrderStatus status) + + + The @Splitter annotation is also applicable to methods that expect either the + Message type or the message payload type, and the return values of the method + should be a collection of any type. If the returned values are not actual Message + objects, then each of them will be sent as the payload of a message. Those messages will be sent to the output + channel as designated for the endpoint on which the @Splitter is defined. + @Splitter +List<LineItem> extractItems(Order order) { + return order.getItems() +} + + + The @Aggregator annotation may be used on a method that accepts a collection + of Messages or Message payload types and whose return value is a single Message or single Object that will + be used as the payload of a Message. + aggregateMessages(List> messages) { ... } + +@Aggregator +public Order aggregateOrder(List items) { ... }]]> + + + Finally, the @Publisher is an annotation that triggers the creation of a Spring + AOP Proxy such that the return value, exception, or method invcation arguments can be sent to a Message Channel. + For example, each time the following method is invoked, its return value will be sent to the "fooChannel": + + The return value is published by default, but you can also configure the payload type: + @Publisher(channel="testChannel", payloadType=MessagePublishingInterceptor.PayloadType.ARGUMENTS) +public void publishArguments(String s, Integer n) { + ... +} + +@Publisher(channel="testChannel", payloadType=MessagePublishingInterceptor.PayloadType.EXCEPTION) +public void publishException() { + throw new RuntimeException("oops!"); +} + +
+
\ No newline at end of file