2. Introduction

This first part of the reference documentation is a high-level overview of Spring AMQP and the underlying concepts and some code snippets that will get you up and running as quickly as possible.

2.1 Quick Tour for the impatient

2.1.1 Introduction

This is the 5 minute tour to get started with Spring AMQP.

Prerequisites: install and run the RabbitMQ broker (http://www.rabbitmq.com/download.html). Then grab the spring-rabbit JAR and all its dependencies - the easiest way to do that is to declare a dependency in your build tool, e.g. for Maven:

<dependency>
  <groupId>org.springframework.amqp</groupId>
  <artifactId>spring-rabbit</artifactId>
  <version>1.6.6.RELEASE</version>
</dependency>

And for gradle:

compile 'org.springframework.amqp:spring-rabbit:1.6.6.RELEASE'

Compatibility

While the default Spring Framework version dependency is 4.2.x, Spring AMQP is generally compatible with earlier versions of Spring Framework. Annotation-based listeners and the RabbitMessagingTemplate require Spring Framework 4.1 or higher, however.

Similarly, the default amqp-client version is 3.6.x but the framework is compatible with versions 3.4.0 and above. However, of course, features that rely on newer client versions will not be available. Note the this refers to the java client library; generally, it will work with older broker versions.

Very, Very Quick

Using plain, imperative Java to send and receive a message:

ConnectionFactory connectionFactory = new CachingConnectionFactory();
AmqpAdmin admin = new RabbitAdmin(connectionFactory);
admin.declareQueue(new Queue("myqueue"));
AmqpTemplate template = new RabbitTemplate(connectionFactory);
template.convertAndSend("myqueue", "foo");
String foo = (String) template.receiveAndConvert("myqueue");

Note that there is a ConnectionFactory in the native Java Rabbit client as well. We are using the Spring abstraction in the code above. We are relying on the default exchange in the broker (since none is specified in the send), and the default binding of all queues to the default exchange by their name (hence we can use the queue name as a routing key in the send). Those behaviours are defined in the AMQP specification.

With XML Configuration

The same example as above, but externalizing the resource configuration to XML:

ApplicationContext context =
    new GenericXmlApplicationContext("classpath:/rabbit-context.xml");
AmqpTemplate template = context.getBean(AmqpTemplate.class);
template.convertAndSend("myqueue", "foo");
String foo = (String) template.receiveAndConvert("myqueue");
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:rabbit="http://www.springframework.org/schema/rabbit"
       xsi:schemaLocation="http://www.springframework.org/schema/rabbit
           http://www.springframework.org/schema/rabbit/spring-rabbit.xsd
           http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd">

    <rabbit:connection-factory id="connectionFactory"/>

    <rabbit:template id="amqpTemplate" connection-factory="connectionFactory"/>

    <rabbit:admin connection-factory="connectionFactory"/>

    <rabbit:queue name="myqueue"/>

</beans>

The <rabbit:admin/> declaration by default automatically looks for beans of type Queue, Exchange and Binding and declares them to the broker on behalf of the user, hence there is no need to use that bean explicitly in the simple Java driver. There are plenty of options to configure the properties of the components in the XML schema - you can use auto-complete features of your XML editor to explore them and look at their documentation.

With Java Configuration

The same example again with the external configuration in Java:

ApplicationContext context =
    new AnnotationConfigApplicationContext(RabbitConfiguration.class);
AmqpTemplate template = context.getBean(AmqpTemplate.class);
template.convertAndSend("myqueue", "foo");
String foo = (String) template.receiveAndConvert("myqueue");

........

@Configuration
public class RabbitConfiguration {

    @Bean
    public ConnectionFactory connectionFactory() {
        return new CachingConnectionFactory("localhost");
    }

    @Bean
    public AmqpAdmin amqpAdmin() {
        return new RabbitAdmin(connectionFactory());
    }

    @Bean
    public RabbitTemplate rabbitTemplate() {
        return new RabbitTemplate(connectionFactory());
    }

    @Bean
    public Queue myQueue() {
       return new Queue("myqueue");
    }
}

2.2 What’s New

2.2.1 Changes in 1.6 Since 1.5

Testing Support

A new testing support library is now provided. See Section 3.4, “Testing Support” for more information.

Builder

Builders are now available providing a fluent API for configuring Queue and Exchange objects. See the section called “Builder API for Queues and Exchanges” for more information.

Namespace Changes

Connection Factory

It is now possible to add a thread-factory to a connection factory bean declaration, for example to name the threads created by the amqp-client library. See Section 3.1.2, “Connection and Resource Management” for more information.

When using CacheMode.CONNECTION, you can now limit the total number of connections allowed. See Section 3.1.2, “Connection and Resource Management” for more information.

Queue Definitions

It is now possible to provide a naming strategy for anonymous queues; see the section called “AnonymousQueue” for more information.

Listener Container Changes

Idle Message Listener Detection

It is now possible to configure listener containers to publish ApplicationEvent s when idle. See the section called “Detecting Idle Asynchronous Consumers” for more information.

Mismatched Queue Detection

By default, when a listener container starts, if queues with mismatched properties or arguments were detected, the container would log the exception but continue to listen. The container now has a property mismatchedQueuesFatal which will prevent the container (and context) from starting if the problem is detected during startup. It will also stop the container if the problem is detected later, such as after recovering from a connection failure. See Section 3.1.15, “Message Listener Container Configuration” for more information.

Listener Container Logging

Now listener container provides its beanName into the internal SimpleAsyncTaskExecutor as a threadNamePrefix. It is useful for logs analysis.

Default Error Handler

The default error handler (ConditionalRejectingErrorHandler) now considers irrecoverable @RabbitListener exceptions as fatal. See Section 3.1.13, “Exception Handling” for more information.

AutoDeclare and RabbitAdmins

See Section 3.1.15, “Message Listener Container Configuration” (autoDeclare) for some changes to the semantics of that option with respect to the use of RabbitAdmin s in the application context.

AmqpTemplate: receive with timeout

A number of new receive() methods with timeout have been introduced for the AmqpTemplate and its RabbitTemplate implementation. See the section called “Polling Consumer” for more information.

AsyncRabbitTemplate

A new AsyncRabbitTemplate has been introduced. This template provides a number of send and receive methods, where the return value is a ListenableFuture, which can be used later to obtain the result either synchronously, or asynchronously. See the section called “AsyncRabbitTemplate” for more information.

RabbitTemplate Changes

1.4.1 introduced the ability to use Direct reply-to when the broker supports it; it is more efficient than using a temporary queue for each reply. This version allows you to override this default behavior and use a temporary queue by setting the useTemporaryReplyQueues property to true. See the section called “RabbitMQ Direct reply-to” for more information.

The RabbitTemplate now supports a user-id-expression (userIdExpression when using Java configuration). See Validated User-ID RabbitMQ documentation and the section called “Validated User Id” for more information.

Message Properties

CorrelationId

The correlationId message property can now be a String. See the section called “Message Properties Converters” for more information.

Long String Headers

Previously, the DefaultMessagePropertiesConverter "converted" headers longer than the long string limit (default 1024) to a DataInputStream (actually it just referenced the LongString's DataInputStream). On output, this header was not converted (except to a String, e.g. java.io.DataInputStream@1d057a39 by calling toString() on the stream).

With this release, long LongString s are now left as LongString s by default; you can access the contents via the getBytes[], toString(), or getStream() methods. A large incoming LongString is now correctly "converted" on output too.

See the section called “Message Properties Converters” for more information.

Inbound Delivery Mode

The deliveryMode property is no longer mapped to the MessageProperties.deliveryMode; this is to avoid unintended propagation if the the same MessageProperties object is used to send an outbound message. Instead, the inbound deliveryMode header is mapped to MessageProperties.receivedDeliveryMode.

See the section called “Message Properties Converters” for more information.

When using annotated endpoints, the header is provided in the header named AmqpHeaders.RECEIVED_DELIVERY_MODE.

See the section called “Annotated Endpoint Method Signature” for more information.

Inbound User ID

The user_id property is no longer mapped to the MessageProperties.userId; this is to avoid unintended propagation if the the same MessageProperties object is used to send an outbound message. Instead, the inbound userId header is mapped to MessageProperties.receivedUserId.

See the section called “Message Properties Converters” for more information.

When using annotated endpoints, the header is provided in the header named AmqpHeaders.RECEIVED_USER_ID.

See the section called “Annotated Endpoint Method Signature” for more information.

RabbitAdmin Changes

Declaration Failures

Previously, the ignoreDeclarationFailures flag only took effect for IOException on the channel (such as mis-matched arguments). It now takes effect for any exception (such as TimeoutException). In addition, a DeclarationExceptionEvent is now published whenever a declaration fails. The RabbitAdmin last declaration event is also available as a property lastDeclarationExceptionEvent. See Section 3.1.10, “Configuring the broker” for more information.

@RabbitListener Changes

Multiple Containers per Bean

When using Java 8 or later, it is now possible to add multiple @RabbitListener annotations to @Bean classes or their methods. When using Java 7 or earlier, you can use the @RabbitListeners container annotation to provide the same functionality. See the section called “@Repeatable @RabbitListener” for more information.

@SendTo SpEL Expressions

@SendTo for routing replies with no replyTo property can now be SpEL expressions evaluated against the request/reply. See the section called “Reply Management” for more information.

@QueueBinding Improvements

You can now specify arguments for queues, exchanges and bindings in @QueueBinding annotations. Header exchanges are now supported by @QueueBinding. See the section called “Annotation-driven Listener Endpoints” for more information.

Delayed Message Exchange

Spring AMQP now has first class support for the RabbitMQ Delayed Message Exchange plugin. See Section 3.1.11, “Delayed Message Exchange” for more information.

Exchange internal flag

Any Exchange definitions can now be marked as internal and the RabbitAdmin will pass the value to the broker when declaring the exchange. See Section 3.1.10, “Configuring the broker” for more information.

CachingConnectionFactory Changes

CachingConnectionFactory Cache Statistics

The CachingConnectionFactory now provides cache properties at runtime and over JMX. See the section called “Runtime Cache Properties” for more information.

Access the Underlying RabbitMQ Connection Factory

A new getter has been added to provide access to the underlying factory. This can be used, for example, to add custom connection properties. See Section 3.1.3, “Adding Custom Client Connection Properties” for more information.

Channel Cache

The default channel cache size has been increased from 1 to 25. See Section 3.1.2, “Connection and Resource Management” for more information.

In addition, the SimpleMessageListenerContainer no longer adjusts the cache size to be at least as large as the number of concurrentConsumers - this was superfluous, since the container consumer channels are never cached.

RabbitConnectionFactoryBean

The factory bean now exposes a property to add client connection properties to connections made by the resulting factory.

Java Deserialization

A "white list" of allowable classes can now be configured when using Java deserialization. It is important to consider creating a white list if you accept messages with serialized java objects from untrusted sources. See the section called “Java Deserialization” for more information.

JSON MessageConverter

Improvements to the JSON message converter now allow the consumption of messages that don’t have type information in message headers. See the section called “Message Conversion for Annotated Methods” and the section called “Jackson2JsonMessageConverter” for more information.

Logging Appenders

Log4j2

A log4j2 appender has been added, and the appenders can now be configured with an addresses property to connect to a broker cluster.

Client Connection Properties

You can now add custom client connection properties to RabbitMQ connections.

See Section 3.2, “Logging Subsystem AMQP Appenders” for more information.

RabbitTemplate Changes

[Important]Important

Previously, a non-transactional RabbitTemplate participated in an existing transaction if it ran on a transactional listener container thread. This was a serious bug; however, users might have relied on this behavior. Starting with version 1.6.2, you must set the channelTransacted boolean on the template for it to participate in the container transaction.

Container Conditional Rollback

When using an external transaction manager (e.g. JDBC), rule-based rollback is now supported when providing the container with a transaction attribute. It is also now more flexible when using a transaction advice. See the section called “Conditional Rollback” for more information.

2.2.2 Earlier Releases

See Section A.2, “Previous Releases” for changes in previous versions.