202 lines
13 KiB
XML
202 lines
13 KiB
XML
<?xml version="1.0" encoding="UTF-8"?>
|
|
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
|
|
<appendix id="namespaces">
|
|
<title>Namespace Support</title>
|
|
<para>
|
|
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.
|
|
</para>
|
|
<para>
|
|
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
|
|
<ulink url="http://www.eaipatterns.com">Enterprise Integration Patterns</ulink>.
|
|
</para>
|
|
<para>
|
|
To enable Spring Integration's core namespace support within your Spring configuration files, add the following
|
|
namespace reference and schema mapping in your top-level 'beans' element:
|
|
<programlisting language="xml"><![CDATA[<beans xmlns="http://www.springframework.org/schema/beans"
|
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
]]><emphasis>xmlns:integration="http://www.springframework.org/schema/integration"</emphasis><![CDATA[
|
|
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
|
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
|
|
]]><emphasis>http://www.springframework.org/schema/integration
|
|
http://www.springframework.org/schema/integration/spring-integration-1.0.xsd"</emphasis>></programlisting>
|
|
</para>
|
|
<para>
|
|
You can choose any name after "xmlns:"; <emphasis>integration</emphasis> 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:
|
|
<programlisting language="xml"><emphasis><beans:beans xmlns="http://www.springframework.org/schema/integration"</emphasis><![CDATA[
|
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
]]><emphasis>xmlns:beans="http://www.springframework.org/schema/beans"</emphasis><![CDATA[
|
|
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
|
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
|
|
http://www.springframework.org/schema/integration
|
|
http://www.springframework.org/schema/integration/spring-integration-1.0.xsd">]]></programlisting>
|
|
</para>
|
|
<para>
|
|
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.
|
|
</para>
|
|
<para>
|
|
Many other namespaces are provided within the Spring Integration distribution. In fact, each adapter type (JMS,
|
|
File, etc.) that provides namespace support defines its elements within a separate schema. In order to use these
|
|
elements, simply add the necessary namespaces with an "xmlns" entry and the corresponding "schemaLocation" mapping.
|
|
For example, the following root element shows several of these namespace declarations:
|
|
<programlisting language="xml"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
|
|
<beans xmlns="http://www.springframework.org/schema/beans"
|
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
xmlns:integration="http://www.springframework.org/schema/integration"
|
|
xmlns:file="http://www.springframework.org/schema/integration/file"
|
|
xmlns:jms="http://www.springframework.org/schema/integration/jms"
|
|
xmlns:mail="http://www.springframework.org/schema/integration/mail"
|
|
xmlns:rmi="http://www.springframework.org/schema/integration/rmi"
|
|
xmlns:ws="http://www.springframework.org/schema/integration/ws"
|
|
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
|
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
|
|
http://www.springframework.org/schema/integration
|
|
http://www.springframework.org/schema/integration/spring-integration-1.0.xsd
|
|
http://www.springframework.org/schema/integration/file
|
|
http://www.springframework.org/schema/integration/file/spring-integration-file-1.0.xsd
|
|
http://www.springframework.org/schema/integration/jms
|
|
http://www.springframework.org/schema/integration/jms/spring-integration-jms-1.0.xsd
|
|
http://www.springframework.org/schema/integration/mail
|
|
http://www.springframework.org/schema/integration/mail/spring-integration-mail-1.0.xsd
|
|
http://www.springframework.org/schema/integration/rmi
|
|
http://www.springframework.org/schema/integration/rmi/spring-integration-rmi-1.0.xsd
|
|
http://www.springframework.org/schema/integration/ws
|
|
http://www.springframework.org/schema/integration/ws/spring-integration-ws-1.0.xsd">
|
|
...
|
|
</beans>]]></programlisting>
|
|
The reference manual provides specific examples of the various elements in their corresponding chapters. Here, the
|
|
main thing to recognize is the consistency of the naming for each namespace URI and schema location.
|
|
</para>
|
|
|
|
<section id="namespace-messagebus">
|
|
<title>Configuring the Message Bus</title>
|
|
<para>
|
|
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:
|
|
<programlisting language="xml"><message-bus/></programlisting>
|
|
</para>
|
|
<para>
|
|
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:
|
|
<programlisting language="xml"><![CDATA[<message-bus/>
|
|
|
|
<channel id="errorChannel" capacity="500"/>]]></programlisting>
|
|
When exceptions occur in a scheduled poller task's execution, those exceptions will be wrapped in
|
|
<classname>ErrorMessages</classname> 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
|
|
<classname>ErrorMessageExceptionTypeRouter</classname> 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
|
|
<classname>Exception</classname> type. However, since most of the errors will already have been wrapped in
|
|
<classname>MessageDeliveryException</classname> or <classname>MessageHandlingException</classname>,
|
|
the <classname>ErrorMessageExceptionTypeRouter</classname> is typically a better option.
|
|
</para>
|
|
<para>
|
|
The 'message-bus' element accepts several more optional attributes. First, you can control whether the
|
|
<classname>MessageBus</classname> will be started automatically (the default) or will require explicit startup
|
|
by invoking its <methodname>start()</methodname> method (<classname>MessageBus</classname> implements
|
|
Spring's <interfacename>Lifecycle</interfacename> interface):
|
|
<programlisting language="xml"><![CDATA[<message-bus auto-startup="false"/>]]></programlisting>
|
|
</para>
|
|
<para>
|
|
Another configurable property is the reference to a <interfacename>TaskScheduler</interfacename> implementation.
|
|
If not provided, a default will be created. The scheduler is responsible for managing the pollers.
|
|
<programlisting language="xml"><![CDATA[<message-bus task-scheduler="someScheduler"/>]]></programlisting>
|
|
When the endpoints are concurrency-enabled with their own 'taskExecutor' reference, the invocation of the handling
|
|
methods will happen within that executor's thread pool and not the main scheduler pool. However, when no
|
|
task-executor is provided for an endpoint's poller, then it will be invoked in the dispatcher's thread
|
|
(with the exception of subscribable channels where the subscribers may be invoked directly).
|
|
</para>
|
|
</section>
|
|
|
|
<section id="annotations">
|
|
<title>Annotations</title>
|
|
<para>
|
|
In addition to the XML namespace support for configuring Message Endpoints, it is also possible to use
|
|
annotations. First, Spring Integration provides the class-level <interfacename>@MessageEndpoint</interfacename>
|
|
as a <emphasis>stereotype</emphasis> annotation meaning that is itself annotated with Spring's @Component
|
|
annotation and therefore is recognized automatically as a bean definition when using Spring component-scanning.
|
|
</para>
|
|
<para>
|
|
Even more importantly are the various Method-level annotations that indicate the annotated method is capable of
|
|
handling a message. The following example demonstrates both:
|
|
<programlisting language="java">@MessageEndpoint
|
|
public class FooService {
|
|
|
|
@ServiceActivator
|
|
public void processMessage(Message message) {
|
|
...
|
|
}
|
|
}</programlisting>
|
|
</para>
|
|
<para>
|
|
Exactly what it means for the method to "handle" the Message depends on the particular annotation. The following
|
|
are available with Spring Integration, and the behavior of each is described in its own chapter or section within
|
|
this reference: @Transformer, @Router, @Splitter, @Aggregator, @ServiceActivator, and @ChannelAdapter.
|
|
</para>
|
|
<note>
|
|
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 method-level annotations.
|
|
</note>
|
|
<para>
|
|
In most cases, the annotated handler method should not require the <classname>Message</classname> type as its
|
|
parameter. Instead, the method parameter type can match the message's payload type.
|
|
<programlisting language="java">public class FooService {
|
|
|
|
@Handler
|
|
public void bar(<emphasis>Foo foo</emphasis>) {
|
|
...
|
|
}
|
|
|
|
}</programlisting>
|
|
</para>
|
|
<para>
|
|
When the method parameter should be mapped from a value in the <classname>MessageHeader</classname>, another
|
|
option is to use the parameter-level <interfacename>@Header</interfacename> annotation. In general, methods
|
|
annotated with the Spring Integration annotations can either accept the <classname>Message</classname> itself, the
|
|
message payload, or a header value (with @Header) as the parameter. In fact, the method can accept a combination,
|
|
such as:
|
|
<programlisting language="java">public class FooService {
|
|
|
|
@ServiceActivator
|
|
public void bar(String payload, @Header("x") int valueX, @Header("y") int valueY) {
|
|
...
|
|
}
|
|
|
|
}</programlisting>
|
|
There is also a @Headers annotation that provides all of the Message headers as a Map:
|
|
<programlisting language="java">public class FooService {
|
|
|
|
@ServiceActivator
|
|
public void bar(String payload, @Headers Map<String, Object> headerMap) {
|
|
...
|
|
}
|
|
|
|
}</programlisting>
|
|
</para>
|
|
<para>
|
|
For several of these annotations, when a Message-handling 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 such an endpoint's output channel will be used if available, and the message header's REPLY_CHANNEL value
|
|
will be the fallback.
|
|
</para>
|
|
</section>
|
|
|
|
</appendix> |