diff --git a/src/reference/docbook/amqp.xml b/src/reference/docbook/amqp.xml
index bac265a7..81c9c58d 100644
--- a/src/reference/docbook/amqp.xml
+++ b/src/reference/docbook/amqp.xml
@@ -584,6 +584,16 @@ public AmqpTemplate rabbitTemplate();
RabbitTemplate.
+
+ Messaging integration
+
+ Starting with version 1.4 RabbitMessagingTemplate, built on top of
+ RabbitTemplate, provides an integration with the
+ Spring Framework messaging abstraction, i.e.
+ org.springframework.messaging.Message. This allows you to create the message to send
+ in generic manner.
+
+
@@ -876,14 +886,23 @@ if (received) {
}]]>
- Asynchronous ConsumerFor asynchronous Message
+ Asynchronous Consumer
+
+
+ Spring AMQP also supports annotated-listener endpoints through the use of the
+ @RabbitListener annotation and provides an open infrastructure to register endpoints
+ programmatically. This is by far the most convenient way to setup an asynchronous consumer, see
+ for more details.
+
+
+ For asynchronous Message
reception, a dedicated component (not the
AmqpTemplate) is involved. That component
is a container for a Message consuming callback. We will look at the
container and its properties in just a moment, but first we should look at
the callback since that is where your application code will be integrated
- with the messaging system. There are a few options for the callback. The
- simplest of these is to implement the
+ with the messaging system. There are a few options for the callback
+ starting with an implementation of the
MessageListener interface:
-
+
+
+ You can subclass the adapter and provide an implementation of getListenerMethodName()
+ to dynamically select different methods based on the message.
+
Now
that you've seen the various options for the Message-listening callback,
@@ -1023,7 +1047,205 @@ container.setConsumerArguments(Collections. singletonMap("x-pri
same reason. When the container is later started, it uses it's reference to
containerAdmin to declare the elements.
-
+
+
+
+ Annotation-driven listener endpoints
+
+ Starting with version 1.4,
+ the easiest way to receive a message asynchronously is to use the annotated listener
+ endpoint infrastructure. In a nutshell, it allows you to expose a method of a managed bean
+ as a Rabbit listener endpoint.
+
+ The idea of the example above is that, whenever a message is available on the
+ org.springframework.amqp.core.Queue "myQueue", the processOrder
+ method is invoked accordingly (in this case, with the payload of the message).
+
+ The annotated endpoint infrastructure creates a message listener container behind the scenes
+ for each annotated method, using a RabbitListenerContainerFactory.
+
+
+ Enable listener endpoint annotations
+
+ To enable support for @RabbitListener annotations add
+ @EnableRabbit to one of your @Configuration classes.
+
+ By default, the infrastructure looks for a bean named rabbitListenerContainerFactory
+ as the source for the factory to use to create message listener containers. In this case, and ignoring the
+ RabbitMQ infrastructure setup, the processOrder method can be invoked with a core
+ poll size of 3 threads and a maximum pool size of 10 threads.
+
+ It is possible to customize the listener container factory to use per annotation or an explicit
+ default can be configured by implementing the RabbitListenerConfigurer
+ interface. The default is only required if at least one endpoint is registered without a specific container
+ factory. See the javadoc for full details and examples.
+
+ If you prefer XML configuration, use the <rabbit:annotation-driven> element.
+
+
+
+
+
+
+
+]]>
+
+
+ Programmatic Endpoint Registration
+
+ RabbitListenerEndpoint provides a model of a Rabbit endpoint and is
+ responsible for configuring the container for that model. The infrastructure allows you to
+ configure endpoints programmatically in addition to the ones that are detected by the
+ RabbitListener annotation. {
+ // processing
+ });
+ registrar.registerEndpoint(endpoint);
+ }
+}]]>
+ In the example above, we used SimpleRabbitListenerEndpoint which provides
+ the actual MessageListener to invoke but you could just as well build your own
+ endpoint variant describing a custom invocation mechanism.
+
+ It should be noted that you could just as well skip the use of @RabbitListener
+ altogether and only register your endpoints programmatically through RabbitListenerConfigurer.
+
+
+ Annotated Endpoint Method Signature
+
+ So far, we have been injecting a simple String in our endpoint but it can actually have a very
+ flexible method signature. Let’s rewrite it to inject the Order with a custom header:
+
+ These are the main elements you can inject in listener endpoints:
+
+
+ The raw org.springframework.amqp.core.Message.
+
+
+ The com.rabbitmq.client.Channel on which the message was received
+
+
+ The org.springframework.messaging.Message representing the incoming AMQP
+ message. Note that this message holds both the custom and the standard headers (as defined
+ by AmqpHeaders).
+
+
+ @Header-annotated method arguments to extract a specific header value,
+ including standard AMQP headers.
+
+
+ @Headers-annotated argument that must also be assignable to
+ java.util.Map for getting access to all headers.
+
+
+ A non-annotated element that is not one of the supported types (i.e. Message
+ and Channel) is considered to be the payload. You can make that explicit by
+ annotating the parameter with @Payload. You can also turn on validation by
+ adding an extra @Valid.
+
+
+
+ The ability to inject Spring’s Message abstraction is particularly useful to benefit from all
+ the information stored in the transport-specific message without relying on transport-specific API.
+ order) { ... }
+]]>
+
+ Handling of method arguments is provided by DefaultMessageHandlerMethodFactory
+ which can be further customized to support additional method arguments. The conversion and validation
+ support can be customized there as well.
+
+ For instance, if we want to make sure our Order is valid before processing it, we can annotate
+ the payload with @Valid and configure the necessary validator as follows:
+
+
+
+ Reply Management
+ The existing support in MessageListenerAdapter already allows your method to
+ have a non-void return type. When that’s the case, the result of the invocation is encapsulated in a
+ message sent either in the address specified in the ReplyToAddress header of
+ the original message or in the default address configured on the listener. That default address can
+ now be set using the @SendTo annotation of the messaging abstraction.
+
+ Assuming our processOrder method should now return an
+ OrderStatus, it is possible to write it as follow to automatically send a reply:
+
+ If you need to set additional headers in a transport-independent manner, you could return a
+ Message instead, something like: processOrder(Order order) {
+ // order processing
+ return MessageBuilder
+ .withPayload(status)
+ .setHeader("code", 1234)
+ .build();
+}]]>
+
diff --git a/src/reference/docbook/index.xml b/src/reference/docbook/index.xml
index 0eca8511..f8560cd3 100644
--- a/src/reference/docbook/index.xml
+++ b/src/reference/docbook/index.xml
@@ -43,6 +43,14 @@
Gunnar
Hillert
+
+ Artem
+ Bilan
+
+
+ Stephane
+ Nicoll
+
2010-2014
diff --git a/src/reference/docbook/whats-new.xml b/src/reference/docbook/whats-new.xml
index 503ffdf0..de2b0a52 100644
--- a/src/reference/docbook/whats-new.xml
+++ b/src/reference/docbook/whats-new.xml
@@ -11,7 +11,7 @@
POJO listeners can be annotated with @RabbitListener, enabled
by @EnableRabbit or <rabbit:annotation-driven />.
Spring Framework 4.1 is required for this feature.
- More documentation to follow.
+ See for more information.
@@ -22,7 +22,7 @@
It uses the RabbitTemplate internally which can be configured
as normal.
Spring Framework 4.1 is required for this feature.
- More documentation to follow.
+ See for more information.