Appendix A. Change History

A.1 Current Release

See Section 2.2, “What’s New”.

A.2 Previous Releases

A.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. [email protected] 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.

A.2.2 Changes in 1.5 Since 1.4

spring-erlang is No Longer Supported

The spring-erlang jar is no longer included in the distribution. Use Section 3.1.12, “RabbitMQ REST API” instead.

CachingConnectionFactory Changes

Empty Addresses Property in CachingConnectionFactory

Previously, if the connection factory was configured with a host/port, but an empty String was also supplied for addresses, the host and port were ignored. Now, an empty addresses String is treated the same as a null, and the host/port will be used.

URI Constructor

The CachingConnectionFactory has an additional constructor, with a URI parameter, to configure the broker connection.

Connection Reset

A new method resetConnection() has been added to allow users to reset the connection (or connections). This might be used, for example, to reconnect to the primary broker after failing over to the secondary broker. This will impact in-process operations. The existing destroy() method does exactly the same, but the new method has a less daunting name.

Properties to Control Container Queue Declaration Behavior

When the listener container consumers start, they attempt to passively declare the queues to ensure they are available on the broker. Previously, if these declarations failed, for example because the queues didn’t exist, or when an HA queue was being moved, the retry logic was fixed at 3 retry attempts at 5 second intervals. If the queue(s) still do not exist, the behavior is controlled by the missingQueuesFatal property (default true). Also, for containers configured to listen from multiple queues, if only a subset of queues are available, the consumer retried the missing queues on a fixed interval of 60 seconds.

These 3 properties (declarationRetries, failedDeclarationRetryInterval, retryDeclarationInterval) are now configurable. See Section 3.1.15, “Message Listener Container Configuration” for more information.

Class Package Change

The RabbitGatewaySupport class has been moved from o.s.amqp.rabbit.core.support to o.s.amqp.rabbit.core.

DefaultMessagePropertiesConverter

The DefaultMessagePropertiesConverter can now be configured to determine the maximum length of a LongString that will be converted to a String rather than a DataInputStream. The converter has an alternative constructor that takes the value as a limit. Previously, this limit was hard-coded at 1024 bytes. (Also available in 1.4.4).

@RabbitListener Improvements

@QueueBinding for @RabbitListener

The bindings attribute has been added to the @RabbitListener annotation as mutually exclusive with the queues attribute to allow the specification of the queue, its exchange and binding for declaration by a RabbitAdmin on the Broker.

SpEL in @SendTo

The default reply address (@SendTo) for a @RabbitListener can now be a SpEL expression.

Multiple Queue Names Via Properties

It is now possible to use a combination of SpEL and property placeholders to specify multiple queues for a listener.

See the section called “Annotation-driven Listener Endpoints” for more information.

Automatic Exchange, Queue, Binding Declaration

It is now possible to declare beans that define a collection of these entities and the RabbitAdmin will add the contents to the list of entities that it will declare when a connection is established. See the section called “Declaring Collections of Exchanges, Queues, Bindings” for more information.

RabbitTemplate Changes

reply-address

The reply-address attribute has been added to the <rabbit-template> component as an alternative reply-queue. See Section 3.1.9, “Request/Reply Messaging” for more information. (Also available in 1.4.4 as a setter on the RabbitTemplate).

Blocking Receive Methods

The RabbitTemplate now supports blocking in receive and convertAndReceive methods. See the section called “Polling Consumer” for more information.

Mandatory with SendAndReceive Methods

When the mandatory flag is set when using sendAndReceive and convertSendAndReceive methods, the calling thread will throw an AmqpMessageReturnedException if the request message can’t be deliverted. See the section called “Reply Timeout” for more information.

Improper Reply Listener Configuration

The framework will attempt to verify proper configuration of a reply listener container when using a named reply queue.

See the section called “Reply Listener Container” for more information.

The RabbitManagementTemplate

The RabbitManagementTemplate has been introduced to monitor and configure the RabbitMQ Broker using the REST API provided by its Management Plugin. See Section 3.1.12, “RabbitMQ REST API” for more information.

Listener Container Bean Names (XML)

[Important]Important

The id attribute on the <listener-container/> element has been removed. Starting with this release, the id on the <listener/> child element is used alone to name the listener container bean created for each listener element.

Normal Spring bean name overrides are applied; if a later <listener/> is parsed with the same id as an existing bean, the new definition will override the existing one. Previously, bean names were composed from the ids of the <listener-container/> and <listener/> elements.

When migrating to this release, if you have id s on your <listener-container/> elements, remove them and set the id on the child <listener/> element instead.

However, to support starting/stopping containers as a group, a new group attribute has been added. When this attribute is defined, the containers created by this element are added to a bean with this name, of type Collection<SimpleMessageListenerContainer. You can iterate over this group to start/stop containers.

Class-Level @RabbitListener

The @RabbitListener annotation can now be applied at the class level. Together with the new @RabbitHandler method annotation, this allows the handler method to be selected based on payload type. See the section called “Multi-Method Listeners” for more information.

SimpleMessageListenerContainer: BackOff support

The SimpleMessageListenerContainer can now be supplied with a BackOff instance for consumer startup recovery. See Section 3.1.15, “Message Listener Container Configuration” for more information.

Channel Close Logging

A mechanism to control the log levels of channel closure has been introduced. See the section called “Logging Channel Close Events”.

Application Events

The SimpleMessageListenerContainer now emits application events when consumers fail. See the section called “Consumer Events” for more information.

Consumer Tag Configuration

Previously, the consumer tags for asynchronous consumers were generated by the broker. With this release, it is now possible to supply a naming strategy to the listener container. See the section called “Consumer Tags”.

MessageListenerAdapter

The MessageListenerAdapter now supports a map of queue names (or consumer tags) to method names, to determine which delegate method to call based on the queue the message was received from.

LocalizedQueueConnectionFactory

A new connection factory that connects to the node in a cluster where a mirrored queue actually resides.

See the section called “Queue Affinity and the LocalizedQueueConnectionFactory”.

Anonymous Queue Naming

Starting with version 1.5.3, you can now control how AnonymousQueue names are generated. See the section called “AnonymousQueue” for more information.

A.2.3 Changes in 1.4 Since 1.3

@RabbitListener Annotation

POJO listeners can be annotated with @RabbitListener, enabled by @EnableRabbit or <rabbit:annotation-driven />. Spring Framework 4.1 is required for this feature. See the section called “Annotation-driven Listener Endpoints” for more information.

RabbitMessagingTemplate

A new RabbitMessagingTemplate is provided to allow users to interact with RabbitMQ using spring-messaging Message`s. It uses the `RabbitTemplate internally which can be configured as normal. Spring Framework 4.1 is required for this feature. See the section called “Messaging integration” for more information.

Listener Container Missing Queues Fatal Attribute

1.3.5 introduced the missingQueuesFatal property on the SimpleMessageListenerContainer. This is now available on the listener container namespace element. See Section 3.1.15, “Message Listener Container Configuration”.

RabbitTemplate ConfirmCallback Interface

The confirm method on this interface has an additional parameter cause. When available, this parameter will contain the reason for a negative acknowledgement (nack). See the section called “Publisher Confirms and Returns”.

RabbitConnectionFactoryBean

A factory bean is now provided to create the underlying RabbitMQ ConnectionFactory used by the CachingConnectionFactory. This enables configuration of SSL options using Spring’s dependency injection. See the section called “Configuring the Underlying Client Connection Factory”.

CachingConnectionFactory

The CachingConnectionFactory now allows the connectionTimeout to be set as a property or as an attribute in the namespace. It sets the property on the underlying RabbitMQ ConnectionFactory See the section called “Configuring the Underlying Client Connection Factory”.

Log Appender

The Logback org.springframework.amqp.rabbit.logback.AmqpAppender has been introduced. It provides similar options like org.springframework.amqp.rabbit.log4j.AmqpAppender. For more info see JavaDocs of these classes.

The Log4j AmqpAppender now supports the deliveryMode property (PERSISTENT or NON_PERSISTENT, default: PERSISTENT). Previously, all log4j messages were PERSISTENT.

The appender also supports modification of the Message before sending - allowing, for example, the addition of custom headers. Subclasses should override the postProcessMessageBeforeSend().

Listener Queues

The listener container now, by default, redeclares any missing queues during startup. A new auto-declare attribute has been added to the <rabbit:listener-container> to prevent these redeclarations. See the section called “auto-delete Queues”.

RabbitTemplate: mandatory and connectionFactorySelector Expressions

The mandatoryExpression and sendConnectionFactorySelectorExpression and receiveConnectionFactorySelectorExpression SpEL Expression`s properties have been added to the `RabbitTemplate. The mandatoryExpression is used to evaluate a mandatory boolean value against each request message, when a ReturnCallback is in use. See the section called “Publisher Confirms and Returns”. The sendConnectionFactorySelectorExpression and receiveConnectionFactorySelectorExpression are used when an AbstractRoutingConnectionFactory is provided, to determine the lookupKey for the target ConnectionFactory at runtime on each AMQP protocol interaction operation. See the section called “Routing Connection Factory”.

Listeners and the Routing Connection Factory

A SimpleMessageListenerContainer can be configured with a routing connection factory to enable connection selection based on the queue names. See the section called “Routing Connection Factory”.

RabbitTemplate: RecoveryCallback option

The recoveryCallback property has been added to be used in the retryTemplate.execute(). See the section called “Adding Retry Capabilities”.

MessageConversionException

This exception is now a subclass of AmqpException; if you have code like the following:

try {
    template.convertAndSend("foo", "bar", "baz");
}
catch (AmqpException e) {
	...
}
catch (MessageConversionException e) {
	...
}

The second catch block will no longer be reachable and needs to be moved above the catch-all AmqpException catch block.

RabbitMQ 3.4 Compatibility

Spring AMQP is now compatible with the RabbitMQ 3.4, including direct reply-to; see the section called “Compatibility” and the section called “RabbitMQ Direct reply-to” for more information.

ContentTypeDelegatingMessageConverter

The ContentTypeDelegatingMessageConverter has been introduced to select the MessageConverter to use, based on the contentType property in the MessageProperties. See Section 3.1.7, “Message Converters” for more information.

A.2.4 Changes in 1.3 Since 1.2

Listener Concurrency

The listener container now supports dynamic scaling of the number of consumers based on workload, or the concurrency can be programmatically changed without stopping the container. See Section 3.1.16, “Listener Concurrency”.

Listener Queues

The listener container now permits the queue(s) on which it is listening to be modified at runtime. Also, the container will now start if at least one of its configured queues is available for use. See Section 3.1.18, “Listener Container Queues”

This listener container will now redeclare any auto-delete queues during startup. See the section called “auto-delete Queues”.

Consumer Priority

The listener container now supports consumer arguments, allowing the x-priority argument to be set. See the section called “Container”.

Exclusive Consumer

The SimpleMessageListenerContainer can now be configured with a single exclusive consumer, preventing other consumers from listening to the queue. See Section 3.1.17, “Exclusive Consumer”.

Rabbit Admin

It is now possible to have the Broker generate the queue name, regardless of durable, autoDelete and exclusive settings. See Section 3.1.10, “Configuring the broker”.

Direct Exchange Binding

Previously, omitting the key attribute from a binding element of a direct-exchange configuration caused the queue or exchange to be bound with an empty string as the routing key. Now it is bound with the the name of the provided Queue or Exchange. Users wishing to bind with an empty string routing key need to specify key="".

AMQP Template

The AmqpTemplate now provides several synchronous receiveAndReply methods. These are implemented by the RabbitTemplate. For more information see Section 3.1.6, “Receiving messages”.

The RabbitTemplate now supports configuring a RetryTemplate to attempt retries (with optional back off policy) for when the broker is not available. For more information see the section called “Adding Retry Capabilities”.

Caching Connection Factory

The caching connection factory can now be configured to cache Connection`s and their `Channel s instead of using a single connection and caching just Channel s. See Section 3.1.2, “Connection and Resource Management”.

Binding Arguments

The <exchange>'s <binding> now supports parsing of the <binding-arguments> sub-element. The <headers-exchange>'s <binding> now can be configured with a key/value attribute pair (to match on a single header) or with a <binding-arguments> sub-element, allowing matching on multiple headers; these options are mutually exclusive. See the section called “Introduction”.

Routing Connection Factory

A new SimpleRoutingConnectionFactory has been introduced, to allow configuration of ConnectionFactories mapping to determine the target ConnectionFactory to use at runtime. See the section called “Routing Connection Factory”.

MessageBuilder and MessagePropertiesBuilder

"Fluent APIs" for building messages and/or message properties is now provided. See the section called “Message Builder API”.

RetryInterceptorBuilder

A "Fluent API" for building listener container retry interceptors is now provided. See the section called “Failures in Synchronous Operations and Options for Retry”.

RepublishMessageRecoverer

This new MessageRecoverer is provided to allow publishing a failed message to another queue (including stack trace information in the header) when retries are exhausted. See the section called “Message Listeners and the Asynchronous Case”.

Default Error Handler (Since 1.3.2)

A default ConditionalRejectingErrorHandler has been added to the listener container. This error handler detects message conversion problems (which are fatal) and instructs the container to reject the message to prevent the broker from continually redelivering the unconvertible message. See Section 3.1.13, “Exception Handling”.

Listener Container 'missingQueuesFatal` Property (Since 1.3.5)

The SimpleMessageListenerContainer now has a property missingQueuesFatal (default true). Previously, missing queues were always fatal. See Section 3.1.15, “Message Listener Container Configuration”.

A.2.5 Changes to 1.2 Since 1.1

RabbitMQ Version

Spring AMQP now using RabbitMQ 3.1.x by default (but retains compatibility with earlier versions). Certain deprecations have been added for features no longer supported by RabbitMQ 3.1.x - federated exchanges and the immediate property on the RabbitTemplate.

Rabbit Admin

The RabbitAdmin now provides an option to allow exchange, queue, and binding declarations to continue when a declaration fails. Previously, all declarations stopped on a failure. By setting ignore-declaration-exceptions, such exceptions are logged (WARN), but further declarations continue. An example where this might be useful is when a queue declaration fails because of a slightly different ttl setting would normally stop other declarations from proceeding.

The RabbitAdmin now provides an additional method getQueueProperties(). This can be used to determine if a queue exists on the broker (returns null for a non-existent queue). In addition, the current number of messages in the queue, as well as the current number of consumers is returned.

Rabbit Template

Previously, when using the ...sendAndReceive() methods were used with a fixed reply queue, two custom headers were used for correlation data and to retain/restore reply queue information. With this release, the standard message property correlationId is used by default, although the user can specifiy a custom property to use instead. In addition, nested replyTo information is now retained internally in the template, instead of using a custom header.

The immediate property is deprecated; users must not set this property when using RabbitMQ 3.0.x or greater.

JSON Message Converters

A Jackson 2.x MessageConverter is now provided, along with the existing converter that uses Jackson 1.x.

Automatic Declaration of Queues, etc

Previously, when declaring queues, exchanges and bindings, it was not possible to define which connection factory was used for the declarations, each RabbitAdmin would declare all components using its connection.

Starting with this release, it is now possible to limit declarations to specific RabbitAdmin instances. See the section called “Conditional Declaration”.

AMQP Remoting

Facilities are now provided for using Spring Remoting techniques, using AMQP as the transport for the RPC calls. For more information see the section called “Spring Remoting with AMQP”

Requested Heart Beats

Several users have asked for the underlying client connection factory’s requestedHeartBeats property to be exposed on the Spring AMQP CachingConnectionFactory. This is now available; previously, it was necessary to configure the AMQP client factory as a separate bean and provide a reference to it in the CachingConnectionFactory.

A.2.6 Changes to 1.1 Since 1.0

General

Spring-AMQP is now built using gradle.

Adds support for publisher confirms and returns.

Adds support for HA queues, and broker failover.

Adds support for Dead Letter Exchanges/Dead Letter Queues.

AMQP Log4j Appender

Adds an option to support adding a message id to logged messages.

Adds an option to allow the specification of a Charset name to be used when converting String s to byte[].