diff --git a/docs/en/spring-amqp/spring-amqp.md b/docs/en/spring-amqp/spring-amqp.md index 272dce804a287574364e4141a3768b33cec57303..539d4f3e69b2c043b3b807c6fe72da495ba1282d 100644 --- a/docs/en/spring-amqp/spring-amqp.md +++ b/docs/en/spring-amqp/spring-amqp.md @@ -1,6 +1,6 @@ # Spring AMQP -## [](#preface)1. Preface +## 1. Preface The Spring AMQP project applies core Spring concepts to the development of AMQP-based messaging solutions. We provide a “template” as a high-level abstraction for sending and receiving messages. @@ -9,36 +9,36 @@ These libraries facilitate management of AMQP resources while promoting the use In all of these cases, you can see similarities to the JMS support in the Spring Framework. For other project-related information, visit the Spring AMQP project [homepage](https://projects.spring.io/spring-amqp/). -## [](#whats-new)2. What’s New +## 2. What’s New -### [](#changes-in-2-4-since-2-3)2.1. Changes in 2.4 Since 2.3 +### 2.1. Changes in 2.4 Since 2.3 This section describes the changes between version 2.4 and version 2.4. See [Change History](#change-history) for changes in previous versions. -#### [](#rabbitlistener-changes)2.1.1. `@RabbitListener` Changes +#### 2.1.1. `@RabbitListener` Changes `MessageProperties` is now available for argument matching. See [Annotated Endpoint Method Signature](#async-annotation-driven-enable-signature) for more information. -#### [](#rabbitadmin-changes)2.1.2. `RabbitAdmin` Changes +#### 2.1.2. `RabbitAdmin` Changes A new property `recoverManualDeclarations` allows recovery of manually declared queues/exchanges/bindings. See [Recovering Auto-Delete Declarations](#declarable-recovery) for more information. -#### [](#remoting-support)2.1.3. Remoting Support +#### 2.1.3. Remoting Support Support remoting using Spring Framework’s RMI support is deprecated and will be removed in 3.0. See [Spring Remoting with AMQP](#remoting) for more information. -## [](#introduction)3. Introduction +## 3. Introduction This first part of the reference documentation is a high-level overview of Spring AMQP and the underlying concepts. It includes some code snippets to get you up and running as quickly as possible. -### [](#quick-tour)3.1. Quick Tour for the impatient +### 3.1. Quick Tour for the impatient -#### [](#introduction-2)3.1.1. Introduction +#### 3.1.1. Introduction This is the five-minute tour to get started with Spring AMQP. @@ -60,13 +60,13 @@ For Gradle, you can do something resembling the following: compile 'org.springframework.amqp:spring-rabbit:2.4.2' ``` -##### [](#compatibility)Compatibility +##### Compatibility The minimum Spring Framework version dependency is 5.2.0. The minimum `amqp-client` Java client library version is 5.7.0. -##### [](#very-very-quick)Very, Very Quick +##### Very, Very Quick This section offers the fastest introduction. @@ -99,7 +99,7 @@ It caches channels (and optionally connections) for reuse. We rely 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 (thus, we can use the queue name as a routing key in the send). Those behaviors are defined in the AMQP specification. -##### [](#with-xml-configuration)With XML Configuration +##### With XML Configuration The following example is the same as the preceding example but externalizes the resource configuration to XML: @@ -136,7 +136,7 @@ As a result, you need not 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)With Java Configuration +##### With Java Configuration The following example repeats the same example as the preceding example but with the external configuration defined in Java: @@ -174,7 +174,7 @@ public class RabbitConfiguration { } ``` -##### [](#with-spring-boot-auto-configuration-and-an-async-pojo-listener)With Spring Boot Auto Configuration and an Async POJO Listener +##### With Spring Boot Auto Configuration and an Async POJO Listener Spring Boot automatically configures the infrastructure beans, as the following example shows: @@ -204,17 +204,17 @@ public class Application { } ``` -## [](#reference)4. Reference +## 4. Reference This part of the reference documentation details the various components that comprise Spring AMQP. The [main chapter](#amqp) covers the core classes to develop an AMQP application. This part also includes a chapter about the [sample applications](#sample-apps). -### [](#amqp)4.1. Using Spring AMQP +### 4.1. Using Spring AMQP This chapter explores the interfaces and classes that are the essential components for developing applications with Spring AMQP. -#### [](#amqp-abstractions)4.1.1. AMQP Abstractions +#### 4.1.1. AMQP Abstractions Spring AMQP consists of two modules (each represented by a JAR in the distribution): `spring-amqp` and `spring-rabbit`. The 'spring-amqp' module contains the `org.springframework.amqp.core` package. @@ -229,7 +229,7 @@ Since AMQP operates at the protocol level, in principle, you can use the RabbitM This overview assumes that you are already familiar with the basics of the AMQP specification. If not, have a look at the resources listed in [Other Resources](#resources) -##### [](#message)`Message` +##### `Message` The 0-9-1 AMQP specification does not define a `Message` class or interface. Instead, when performing an operation such as `basicPublish()`, the content is passed as a byte-array argument and additional properties are passed in as separate arguments. @@ -265,7 +265,7 @@ You can also extend those properties with user-defined 'headers' by calling the | |Starting with versions `1.5.7`, `1.6.11`, `1.7.4`, and `2.0.0`, if a message body is a serialized `Serializable` java object, it is no longer deserialized (by default) when performing `toString()` operations (such as in log messages).
This is to prevent unsafe deserialization.
By default, only `java.util` and `java.lang` classes are deserialized.
To revert to the previous behavior, you can add allowable class/package patterns by invoking `Message.addAllowedListPatterns(…​)`.
A simple `` **wildcard is supported, for example `com.something.`**`, *.MyClass`.
Bodies that cannot be deserialized are represented by `byte[]` in log messages.| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#exchange)Exchange +##### Exchange The `Exchange` interface represents an AMQP Exchange, which is what a Message Producer sends to. Each Exchange within a virtual host of a broker has a unique name as well as a few other properties. @@ -299,7 +299,7 @@ For much more information about these and the other Exchange types, see [Other R | |The AMQP specification also requires that any broker provide a “default” direct exchange that has no name.
All queues that are declared are bound to that default `Exchange` with their names as routing keys.
You can learn more about the default Exchange’s usage within Spring AMQP in [`AmqpTemplate`](#amqp-template).| |---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#queue)Queue +##### Queue The `Queue` class represents the component from which a message consumer receives messages. Like the various `Exchange` classes, our implementation is intended to be an abstract representation of this core AMQP type. @@ -340,7 +340,7 @@ For that reason, the 'exclusive' and 'autoDelete' properties of an auto-generate | |See the section on queues in [Configuring the Broker](#broker-configuration) for information about declaring queues by using namespace support, including queue arguments.| |---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#binding)Binding +##### Binding Given that a producer sends to an exchange and a consumer receives from a queue, the bindings that connect queues to exchanges are critical for connecting those producers and consumers via messaging. In Spring AMQP, we define a `Binding` class to represent those connections. @@ -382,7 +382,7 @@ There is also a convenient base class that further simplifies that approach for The `AmqpTemplate` is also defined within the core package. As one of the main components involved in actual AMQP messaging, it is discussed in detail in its own section (see [`AmqpTemplate`](#amqp-template)). -#### [](#connections)4.1.2. Connection and Resource Management +#### 4.1.2. Connection and Resource Management Whereas the AMQP model we described in the previous section is generic and applicable to all implementations, when we get into the management of resources, the details are specific to the broker implementation. Therefore, in this section, we focus on code that exists only within our “spring-rabbit” module since, at this point, RabbitMQ is the only supported implementation. @@ -390,7 +390,7 @@ Therefore, in this section, we focus on code that exists only within our “spri The central component for managing a connection to the RabbitMQ broker is the `ConnectionFactory` interface. The responsibility of a `ConnectionFactory` implementation is to provide an instance of `org.springframework.amqp.rabbit.connection.Connection`, which is a wrapper for `com.rabbitmq.client.Connection`. -##### [](#choosing-factory)Choosing a Connection Factory +##### Choosing a Connection Factory There are three connection factories to chose from @@ -411,7 +411,7 @@ Simple publisher confirmations are supported by all three factories. When configuring a `RabbitTemplate` to use a [separate connection](#separate-connection), you can now, starting with version 2.3.2, configure the publishing connection factory to be a different type. By default, the publishing factory is the same type and any properties set on the main factory are also propagated to the publishing factory. -###### [](#pooledchannelconnectionfactory)`PooledChannelConnectionFactory` +###### `PooledChannelConnectionFactory` This factory manages a single connection and two pools of channels, based on the Apache Pool2. One pool is for transactional channels, the other is for non-transactional channels. @@ -437,7 +437,7 @@ PooledChannelConnectionFactory pcf() throws Exception { } ``` -###### [](#threadchannelconnectionfactory)`ThreadChannelConnectionFactory` +###### `ThreadChannelConnectionFactory` This factory manages a single connection and two `ThreadLocal` s, one for transactional channels, the other for non-transactional channels. This factory ensures that all operations on the same thread use the same channel (as long as it remains open). @@ -446,7 +446,7 @@ To avoid memory leaks, if your application uses many short-lived threads, you mu Starting with version 2.3.7, a thread can transfer its channel(s) to another thread. See [Strict Message Ordering in a Multi-Threaded Environment](#multi-strict) for more information. -###### [](#cachingconnectionfactory)`CachingConnectionFactory` +###### `CachingConnectionFactory` The third implementation provided is the `CachingConnectionFactory`, which, by default, establishes a single connection proxy that can be shared by the application. Sharing of the connection is possible since the “unit of work” for messaging with AMQP is actually a “channel” (in some ways, this is similar to the relationship between a connection and a session in JMS). @@ -584,12 +584,12 @@ The following example with a custom thread factory that prefixes thread names wi ``` -##### [](#addressresolver)AddressResolver +##### AddressResolver Starting with version 2.1.15, you can now use an `AddressResover` to resolve the connection address(es). This will override any settings of the `addresses` and `host/port` properties. -##### [](#naming-connections)Naming Connections +##### Naming Connections Starting with version 1.7, a `ConnectionNameStrategy` is provided for the injection into the `AbstractionConnectionFactory`. The generated name is used for the application-specific identification of the target RabbitMQ connection. @@ -629,7 +629,7 @@ The property must exist in the application context’s `Environment`. | |When using Spring Boot and its autoconfigured connection factory, you need only declare the `ConnectionNameStrategy` `@Bean`.
Boot auto-detects the bean and wires it into the factory.| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#blocked-connections-and-resource-constraints)Blocked Connections and Resource Constraints +##### Blocked Connections and Resource Constraints The connection might be blocked for interaction from the broker that corresponds to the [Memory Alarm](https://www.rabbitmq.com/memory.html). Starting with version 2.0, the `org.springframework.amqp.rabbit.connection.Connection` can be supplied with `com.rabbitmq.client.BlockedListener` instances to be notified for connection blocked and unblocked events. @@ -646,7 +646,7 @@ The `ConnectionNameStrategy` for the publisher connection is the same as the pri Starting with version 1.7.7, an `AmqpResourceNotAvailableException` is provided, which is thrown when `SimpleConnection.createChannel()` cannot create a `Channel` (for example, because the `channelMax` limit is reached and there are no available channels in the cache). You can use this exception in the `RetryPolicy` to recover the operation after some back-off. -##### [](#connection-factory)Configuring the Underlying Client Connection Factory +##### Configuring the Underlying Client Connection Factory The `CachingConnectionFactory` uses an instance of the Rabbit client `ConnectionFactory`. A number of configuration properties are passed through (`host, port, userName, password, requestedHeartBeat, and connectionTimeout` for example) when setting the equivalent property on the `CachingConnectionFactory`. @@ -662,7 +662,7 @@ For convenience, a factory bean is provided to assist in configuring the connect | |The 4.0.x client enables automatic recovery by default.
While compatible with this feature, Spring AMQP has its own recovery mechanisms and the client recovery feature generally is not needed.
We recommend disabling `amqp-client` automatic recovery, to avoid getting `AutoRecoverConnectionNotCurrentlyOpenException` instances when the broker is available but the connection has not yet recovered.
You may notice this exception, for example, when a `RetryTemplate` is configured in a `RabbitTemplate`, even when failing over to another broker in a cluster.
Since the auto-recovering connection recovers on a timer, the connection may be recovered more quickly by using Spring AMQP’s recovery mechanisms.
Starting with version 1.7.1, Spring AMQP disables `amqp-client` automatic recovery unless you explicitly create your own RabbitMQ connection factory and provide it to the `CachingConnectionFactory`.
RabbitMQ `ConnectionFactory` instances created by the `RabbitConnectionFactoryBean` also have the option disabled by default.| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#rabbitconnectionfactorybean-configuring-ssl)`RabbitConnectionFactoryBean` and Configuring SSL +##### `RabbitConnectionFactoryBean` and Configuring SSL Starting with version 1.4, a convenient `RabbitConnectionFactoryBean` is provided to enable convenient configuration of SSL properties on the underlying client connection factory by using dependency injection. Other setters delegate to the underlying factory. @@ -710,7 +710,7 @@ discrete values. | |Starting with version 2.2.5, the factory bean will always use TLS v1.2 by default; previously, it used v1.1 in some cases and v1.2 in others (depending on other properties).
If you need to use v1.1 for some reason, set the `sslAlgorithm` property: `setSslAlgorithm("TLSv1.1")`.| |---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#cluster)Connecting to a Cluster +##### Connecting to a Cluster To connect to a cluster, configure the `addresses` property on the `CachingConnectionFactory`: @@ -738,7 +738,7 @@ public CachingConnectionFactory ccf() { } ``` -##### [](#routing-connection-factory)Routing Connection Factory +##### Routing Connection Factory Starting with version 1.3, the `AbstractRoutingConnectionFactory` has been introduced. This factory provides a mechanism to configure mappings for several `ConnectionFactories` and determine a target `ConnectionFactory` by some `lookupKey` at runtime. @@ -802,7 +802,7 @@ For example, with lookup key qualifier `thing1` and a container listening to que | |The target (and default, if provided) connection factories must have the same settings for publisher confirms and returns.
See [Publisher Confirms and Returns](#cf-pub-conf-ret).| |---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#queue-affinity)Queue Affinity and the `LocalizedQueueConnectionFactory` +##### Queue Affinity and the `LocalizedQueueConnectionFactory` When using HA queues in a cluster, for the best performance, you may want to connect to the physical broker where the lead queue resides. @@ -855,7 +855,7 @@ public LocalizedQueueConnectionFactory queueAffinityCF( Notice that the first three parameters are arrays of `addresses`, `adminUris`, and `nodes`. These are positional in that, when a container attempts to connect to a queue, it uses the admin API to determine which node is the lead for the queue and connects to the address in the same array position as that node. -##### [](#cf-pub-conf-ret)Publisher Confirms and Returns +##### Publisher Confirms and Returns Confirmed (with correlation) and returned messages are supported by setting the `CachingConnectionFactory` property `publisherConfirmType` to `ConfirmType.CORRELATED` and the `publisherReturns` property to 'true'. @@ -869,7 +869,7 @@ See also `simplePublisherConfirms` in [Scoped Operations](#scoped-operations). | |For some more background information, see the blog post by the RabbitMQ team titled [Introducing Publisher Confirms](https://www.rabbitmq.com/blog/2011/02/10/introducing-publisher-confirms/).| |---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#connection-channel-listeners)Connection and Channel Listeners +##### Connection and Channel Listeners The connection factory supports registering `ConnectionListener` and `ChannelListener` implementations. This allows you to receive notifications for connection and channel related events. @@ -908,7 +908,7 @@ public interface ChannelListener { See [Publishing is Asynchronous — How to Detect Successes and Failures](#publishing-is-async) for one scenario where you might want to register a `ChannelListener`. -##### [](#channel-close-logging)Logging Channel Close Events +##### Logging Channel Close Events Version 1.5 introduced a mechanism to enable users to control logging levels. @@ -927,7 +927,7 @@ To modify this behavior, you can inject a custom `ConditionalExceptionLogger` in See also [Consumer Events](#consumer-events). -##### [](#runtime-cache-properties)Runtime Cache Properties +##### Runtime Cache Properties Staring with version 1.6, the `CachingConnectionFactory` now provides cache statistics through the `getCacheProperties()`method. These statistics can be used to tune the cache to optimize it in production. @@ -966,7 +966,7 @@ The `cacheMode` property (`CHANNEL` or `CONNECTION`) is also included. Figure 1. JVisualVM Example -##### [](#auto-recovery)RabbitMQ Automatic Connection/Topology recovery +##### RabbitMQ Automatic Connection/Topology recovery Since the first version of Spring AMQP, the framework has provided its own connection and channel recovery in the event of a broker failure. Also, as discussed in [Configuring the Broker](#broker-configuration), the `RabbitAdmin` re-declares any infrastructure beans (queues and others) when the connection is re-established. @@ -979,7 +979,7 @@ This means any consumers you create within your code (perhaps via `RabbitTemplat | |Only elements (queues, exchanges, bindings) that are defined as beans will be re-declared after a connection failure.
Elements declared by invoking `RabbitAdmin.declare*()` methods directly from user code are unknown to the framework and therefore cannot be recovered.
If you have a need for a variable number of declarations, consider defining a bean, or beans, of type `Declarables`, as discussed in [Declaring Collections of Exchanges, Queues, and Bindings](#collection-declaration).| |---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#custom-client-props)4.1.3. Adding Custom Client Connection Properties +#### 4.1.3. Adding Custom Client Connection Properties The `CachingConnectionFactory` now lets you access the underlying connection factory to allow, for example, setting custom client properties. @@ -991,7 +991,7 @@ connectionFactory.getRabbitConnectionFactory().getClientProperties().put("thing1 These properties appear in the RabbitMQ Admin UI when viewing the connection. -#### [](#amqp-template)4.1.4. `AmqpTemplate` +#### 4.1.4. `AmqpTemplate` As with many other high-level abstractions provided by the Spring Framework and related projects, Spring AMQP provides a “template” that plays a central role. The interface that defines the main operations is called `AmqpTemplate`. @@ -1009,7 +1009,7 @@ We will explore message sending and reception, respectively, in [Sending Message See also [Async Rabbit Template](#async-template). -##### [](#template-retry)Adding Retry Capabilities +##### Adding Retry Capabilities Starting with version 1.3, you can now configure the `RabbitTemplate` to use a `RetryTemplate` to help with handling problems with broker connectivity. See the [spring-retry](https://github.com/spring-projects/spring-retry) project for complete information. @@ -1079,7 +1079,7 @@ retryTemplate.execute( In this case, you would **not** inject a `RetryTemplate` into the `RabbitTemplate`. -##### [](#publishing-is-async)Publishing is Asynchronous — How to Detect Successes and Failures +##### Publishing is Asynchronous — How to Detect Successes and Failures Publishing messages is an asynchronous mechanism and, by default, messages that cannot be routed are dropped by RabbitMQ. For successful publishing, you can receive an asynchronous confirm, as described in [Correlated Publisher Confirms and Returns](#template-confirms). @@ -1116,7 +1116,7 @@ You can examine the signal’s `reason` property to determine the problem that o To detect the exception on the sending thread, you can `setChannelTransacted(true)` on the `RabbitTemplate` and the exception is detected on the `txCommit()`. However, **transactions significantly impede performance**, so consider this carefully before enabling transactions for just this one use case. -##### [](#template-confirms)Correlated Publisher Confirms and Returns +##### Correlated Publisher Confirms and Returns The `RabbitTemplate` implementation of `AmqpTemplate` supports publisher confirms and returns. @@ -1193,7 +1193,7 @@ It is guaranteed that the returned message is set before the future is set with See also [Scoped Operations](#scoped-operations) for a simpler mechanism for waiting for publisher confirms. -##### [](#scoped-operations)Scoped Operations +##### Scoped Operations Normally, when using the template, a `Channel` is checked out of the cache (or created), used for the operation, and returned to the cache for reuse. In a multi-threaded environment, there is no guarantee that the next operation uses the same channel. @@ -1267,7 +1267,7 @@ Boolean result = this.template.invoke(t -> { | |Scoped operations are bound to a thread.
See [Strict Message Ordering in a Multi-Threaded Environment](#multi-strict) for a discussion about strict ordering in a multi-threaded environment.| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#multi-strict)Strict Message Ordering in a Multi-Threaded Environment +##### Strict Message Ordering in a Multi-Threaded Environment The discussion in [Scoped Operations](#scoped-operations) applies only when the operations are performed on the same thread. @@ -1447,7 +1447,7 @@ class Service { | |Once the `prepareSwitchContext` is called, if the current thread performs any more operations, they will be performed on a new channel.
It is important to close the thread-bound channel when it is no longer needed.| |---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#template-messaging)Messaging Integration +##### Messaging Integration Starting with version 1.4, `RabbitMessagingTemplate` (built on top of `RabbitTemplate`) provides an integration with the Spring Framework messaging abstraction — that is,`org.springframework.messaging.Message`. This lets you send and receive messages by using the `spring-messaging` `Message` abstraction. @@ -1462,7 +1462,7 @@ amqpMessageConverter.setPayloadConverter(myPayloadConverter); rabbitMessagingTemplate.setAmqpMessageConverter(amqpMessageConverter); ``` -##### [](#template-user-id)Validated User Id +##### Validated User Id Starting with version 1.6, the template now supports a `user-id-expression` (`userIdExpression` when using Java configuration). If a message is sent, the user id property is set (if not already set) after evaluating this expression. @@ -1479,7 +1479,7 @@ The following examples show how to use the `user-id-expression` attribute: The first example is a literal expression. The second obtains the `username` property from a connection factory bean in the application context. -##### [](#separate-connection)Using a Separate Connection +##### Using a Separate Connection Starting with version 2.0.2, you can set the `usePublisherConnection` property to `true` to use a different connection to that used by listener containers, when possible. This is to avoid consumers being blocked when a producer is blocked for any reason. @@ -1489,7 +1489,7 @@ If the rabbit template is running in a transaction started by the listener conta | |In general, you should not use a `RabbitAdmin` with a template that has this set to `true`.
Use the `RabbitAdmin` constructor that takes a connection factory.
If you use the other constructor that takes a template, ensure the template’s property is `false`.
This is because, often, an admin is used to declare queues for listener containers.
Using a template that has the property set to `true` would mean that exclusive queues (such as `AnonymousQueue`) would be declared on a different connection to that used by listener containers.
In that case, the queues cannot be used by the containers.| |---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#sending-messages)4.1.5. Sending Messages +#### 4.1.5. Sending Messages When sending a message, you can use any of the following methods: @@ -1556,7 +1556,7 @@ template.setRoutingKey("queue.helloWorld"); // but we'll always send to this Que template.send(new Message("Hello World".getBytes(), someProperties)); ``` -##### [](#message-builder)Message Builder API +##### Message Builder API Starting with version 1.3, a message builder API is provided by the `MessageBuilder` and `MessagePropertiesBuilder`. These methods provide a convenient “fluent” means of creating a message or message properties. @@ -1646,7 +1646,7 @@ The following example shows how to use the `postProcess` method: CorrelationData postProcess(Message message, CorrelationData correlationData); ``` -##### [](#publisher-returns)Publisher Returns +##### Publisher Returns When the template’s `mandatory` property is `true`, returned messages are provided by the callback described in [`AmqpTemplate`](#amqp-template). @@ -1656,7 +1656,7 @@ Bean references, such as `@myBean.isMandatory(#root)`, can be used in the expres Publisher returns can also be used internally by the `RabbitTemplate` in send and receive operations. See [Reply Timeout](#reply-timeout) for more information. -##### [](#template-batching)Batching +##### Batching Version 1.4.2 introduced the `BatchingRabbitTemplate`. This is a subclass of `RabbitTemplate` with an overridden `send` method that batches messages according to the `BatchingStrategy`. @@ -1697,7 +1697,7 @@ This is communicated to the receiving system by setting the `springBatchFormat` However, see [@RabbitListener with Batching](#receiving-batch) for more information. -#### [](#receiving-messages)4.1.6. Receiving Messages +#### 4.1.6. Receiving Messages Message reception is always a little more complicated than sending. There are two ways to receive a `Message`. @@ -1705,7 +1705,7 @@ The simpler option is to poll for one `Message` at a time with a polling method The more complicated yet more common approach is to register a listener that receives `Messages` on-demand, asynchronously. We consider an example of each approach in the next two sub-sections. -##### [](#polling-consumer)Polling Consumer +##### Polling Consumer The `AmqpTemplate` itself can be used for polled `Message` reception. By default, if no message is available, `null` is returned immediately. @@ -1799,7 +1799,7 @@ if (received) { } ``` -##### [](#async-consumer)Asynchronous Consumer +##### 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 [Annotation-driven Listener Endpoints](#async-annotation-driven) for more details.| |---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| @@ -1807,7 +1807,7 @@ if (received) { | |The prefetch default value used to be 1, which could lead to under-utilization of efficient consumers.
Starting with version 2.0, the default prefetch value is now 250, which should keep consumers busy in most common scenarios and
thus improve throughput.

There are, nevertheless, scenarios where the prefetch value should be low:

* For large messages, especially if the processing is slow (messages could add up to a large amount of memory in the client process)

* When strict message ordering is necessary (the prefetch value should be set back to 1 in this case)

* Other special cases

Also, with low-volume messaging and multiple consumers (including concurrency within a single listener container instance), you may wish to reduce the prefetch to get a more even distribution of messages across consumers.

See [Message Listener Container Configuration](#containerAttributes).

For more background about prefetch, see this post about [consumer utilization in RabbitMQ](https://www.rabbitmq.com/blog/2014/04/14/finding-bottlenecks-with-rabbitmq-3-3/)and this post about [queuing theory](https://www.rabbitmq.com/blog/2012/05/11/some-queuing-theory-throughput-latency-and-bandwidth/).| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -###### [](#message-listener)Message Listener +###### Message Listener For asynchronous `Message` reception, a dedicated component (not the `AmqpTemplate`) is involved. That component is a container for a `Message`-consuming callback. @@ -1834,7 +1834,7 @@ public interface ChannelAwareMessageListener { | |In version 2.1, this interface moved from package `o.s.amqp.rabbit.core` to `o.s.amqp.rabbit.listener.api`.| |---|-----------------------------------------------------------------------------------------------------------| -###### [](#message-listener-adapter)`MessageListenerAdapter` +###### `MessageListenerAdapter` If you prefer to maintain a stricter separation between your application logic and the messaging API, you can rely upon an adapter implementation that is provided by the framework. This is often referred to as “Message-driven POJO” support. @@ -1906,7 +1906,7 @@ public void handleMessage(Object object, Channel channel, Message message) throw } ``` -###### [](#container)Container +###### Container Now that you have seen the various options for the `Message`-listening callback, we can turn our attention to the container. Basically, the container handles the “active” responsibilities so that the listener callback can remain passive. @@ -1982,7 +1982,7 @@ public class ExampleAmqpConfiguration { } ``` -###### [](#consumer-priority)Consumer Priority +###### Consumer Priority Starting with RabbitMQ Version 3.2, the broker now supports consumer priority (see [Using Consumer Priorities with RabbitMQ](https://www.rabbitmq.com/blog/2013/12/16/using-consumer-priorities-with-rabbitmq/)). This is enabled by setting the `x-priority` argument on the consumer. @@ -2004,7 +2004,7 @@ For convenience, the namespace provides the `priority` attribute on the `listene Starting with version 1.3, you can modify the queues on which the container listens at runtime. See [Listener Container Queues](#listener-queues). -###### [](#lc-auto-delete)`auto-delete` Queues +###### `auto-delete` Queues When a container is configured to listen to `auto-delete` queues, the queue has an `x-expires` option, or the [Time-To-Live](https://www.rabbitmq.com/ttl.html) policy is configured on the Broker, the queue is removed by the broker when the container is stopped (that is, when the last consumer is cancelled). Before version 1.3, the container could not be restarted because the queue was missing. @@ -2036,7 +2036,7 @@ In this case, the queue and exchange are declared by `containerAdmin`, which has Also, the container is not started for the same reason. When the container is later started, it uses its reference to `containerAdmin` to declare the elements. -##### [](#de-batching)Batched Messages +##### Batched Messages Batched messages (created by a producer) are automatically de-batched by listener containers (using the `springBatchFormat` message header). Rejecting any message from a batch causes the entire batch to be rejected. @@ -2049,7 +2049,7 @@ Implement `BatchMessageListener` or `ChannelAwareBatchMessageListener` when `con Starting with version 2.2.7 both the `SimpleMessageListenerContainer` and `DirectMessageListenerContainer` can debatch [producer created batches](#template-batching) as `List`. See [@RabbitListener with Batching](#receiving-batch) for information about using this feature with `@RabbitListener`. -##### [](#consumer-events)Consumer Events +##### Consumer Events The containers publish application events whenever a listener (consumer) experiences a failure of some kind. @@ -2092,7 +2092,7 @@ Several other events are published at various stages of the container lifecycle: * `MissingQueueEvent`: When a missing queue is detected. -##### [](#consumerTags)Consumer Tags +##### Consumer Tags You can provide a strategy to generate consumer tags. By default, the consumer tag is generated by the broker. @@ -2110,7 +2110,7 @@ The queue is made available so that it can (optionally) be used in the tag. See [Message Listener Container Configuration](#containerAttributes). -##### [](#async-annotation-driven)Annotation-driven Listener Endpoints +##### Annotation-driven Listener Endpoints The easiest way to receive a message asynchronously is to use the annotated listener endpoint infrastructure. In a nutshell, it lets you expose a method of a managed bean as a Rabbit listener endpoint. @@ -2225,7 +2225,7 @@ The `value` must resolve to something that can be converted by the `DefaultConve If a name resolves to `null` or an empty `String`, that `@Argument` is ignored. -###### [](#meta-annotation-driven)Meta-annotations +###### Meta-annotations Sometimes you may want to use the same configuration for multiple listeners. To reduce the boilerplate configuration, you can use meta-annotations to create your own listener annotation. @@ -2291,7 +2291,7 @@ static @interface MyListeners { } ``` -###### [](#async-annotation-driven-enable)Enable Listener Endpoint Annotations +###### Enable Listener Endpoint Annotations To enable support for `@RabbitListener` annotations, you can add `@EnableRabbit` to one of your `@Configuration` classes. The following example shows how to do so: @@ -2404,7 +2404,7 @@ public void manual1(String in, Channel channel, } ``` -###### [](#async-annotation-conversion)Message Conversion for Annotated Methods +###### Message Conversion for Annotated Methods There are two conversion steps in the pipeline before invoking the listener. The first step uses a `MessageConverter` to convert the incoming Spring AMQP `Message` to a Spring-messaging `Message`. @@ -2501,7 +2501,7 @@ public class AppConfig implements RabbitListenerConfigurer { | |For multi-method listeners (see [Multi-method Listeners](#annotation-method-selection)), the method selection is based on the payload of the message **after the message conversion**.
The method argument converter is called only after the method has been selected.| |---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -###### [](#custom-argument-resolver)Adding a Custom `HandlerMethodArgumentResolver` to @RabbitListener +###### Adding a Custom `HandlerMethodArgumentResolver` to @RabbitListener Starting with version 2.3.7 you are able to add your own `HandlerMethodArgumentResolver` and resolve custom method parameters. All you need is to implement `RabbitListenerConfigurer` and use method `setCustomMethodArgumentResolvers()` from class `RabbitListenerEndpointRegistrar`. @@ -2535,7 +2535,7 @@ class CustomRabbitConfig implements RabbitListenerConfigurer { } ``` -###### [](#async-annotation-driven-registration)Programmatic Endpoint Registration +###### Programmatic Endpoint Registration `RabbitListenerEndpoint` provides a model of a Rabbit endpoint and is responsible for configuring the container for that model. The infrastructure lets you configure endpoints programmatically in addition to the ones that are detected by the `RabbitListener` annotation. @@ -2562,7 +2562,7 @@ In the preceding example, we used `SimpleRabbitListenerEndpoint`, which provides It should be noted that you could just as well skip the use of `@RabbitListener` altogether and register your endpoints programmatically through `RabbitListenerConfigurer`. -###### [](#async-annotation-driven-enable-signature)Annotated Endpoint Method Signature +###### 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. The following example rewrites it to inject the `Order` with a custom header: @@ -2631,7 +2631,7 @@ public class AppConfig implements RabbitListenerConfigurer { } ``` -###### [](#rabbit-validation)@RabbitListener @Payload Validation +###### @RabbitListener @Payload Validation Starting with version 2.3.7, it is now easier to add a `Validator` to validate `@RabbitListener` and `@RabbitHandler` `@Payload` arguments. Now, you can simply add the validator to the registrar itself. @@ -2696,7 +2696,7 @@ public RabbitListenerErrorHandler validationErrorHandler() { } ``` -###### [](#annotation-multiple-queues)Listening to Multiple Queues +###### Listening to Multiple Queues When you use the `queues` attribute, you can specify that the associated container can listen to multiple queues. You can use a `@Header` annotation to make the queue name from which a message was received available to the POJO @@ -2733,7 +2733,7 @@ public class MyService { Prior to version 1.5, only a single queue could be specified this way. Each queue needed a separate property. -###### [](#async-annotation-driven-reply)Reply Management +###### Reply Management The existing support in `MessageListenerAdapter` already lets your method have a non-void return type. When that is the case, the result of the invocation is encapsulated in a message sent to the the address specified in the `ReplyToAddress` header of the original message, or to the default address configured on the listener. @@ -2866,7 +2866,7 @@ public String listen(Message in) { } ``` -###### [](#reply-content-type)Reply ContentType +###### Reply ContentType If you are using a sophisticated message converter, such as the `ContentTypeDelegatingMessageConverter`, you can control the content type of the reply by setting the `replyContentType` property on the listener. This allows the converter to select the appropriate delegate converter for the reply. @@ -2913,7 +2913,7 @@ This content type will be passed in the `MessageProperties` to the converter. By default, for backwards compatibility, any content type property set by the converter will be overwritten by this value after conversion. If you wish to override that behavior, also set the `AmqpHeaders.CONTENT_TYPE_CONVERTER_WINS` to `true` and any value set by the converter will be retained. -###### [](#annotation-method-selection)Multi-method Listeners +###### Multi-method Listeners Starting with version 1.5.0, you can specify the `@RabbitListener` annotation at the class level. Together with the new `@RabbitHandler` annotation, this lets a single listener invoke different methods, based on @@ -2959,14 +2959,14 @@ At most, one method can be so designated. | |`@RabbitHandler` is intended only for processing message payloads after conversion, if you wish to receive the unconverted raw `Message` object, you must use `@RabbitListener` on the method, not the class.| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -###### [](#repeatable-rabbit-listener)`@Repeatable` `@RabbitListener` +###### `@Repeatable` `@RabbitListener` Starting with version 1.6, the `@RabbitListener` annotation is marked with `@Repeatable`. This means that the annotation can appear on the same annotated element (method or class) multiple times. In this case, a separate listener container is created for each annotation, each of which invokes the same listener`@Bean`. Repeatable annotations can be used with Java 8 or above. -###### [](#proxy-rabbitlistener-and-generics)Proxy `@RabbitListener` and Generics +###### Proxy `@RabbitListener` and Generics If your service is intended to be proxied (for example, in the case of `@Transactional`), you should keep in mind some considerations when the interface has generic parameters. @@ -3008,7 +3008,7 @@ static class TxServiceImpl implements TxService { } ``` -###### [](#annotation-error-handling)Handling Exceptions +###### Handling Exceptions By default, if an annotated listener method throws an exception, it is thrown to the container and the message are requeued and redelivered, discarded, or routed to a dead letter exchange, depending on the container and broker configuration. Nothing is returned to the sender. @@ -3060,7 +3060,7 @@ Starting with version 2.2.18, if a message conversion exception is thrown, the e This allows the application to send some result to the caller, indicating that a badly-formed message was received. Previously, such errors were thrown and handled by the container. -###### [](#container-management)Container Management +###### Container Management Containers created for annotations are not registered with the application context. You can obtain a collection of all containers by invoking `getListenerContainers()` on the`RabbitListenerEndpointRegistry` bean. @@ -3076,7 +3076,7 @@ Starting with version 1.5, you can now assign a `group` to the container on the This provides a mechanism to get a reference to a subset of containers. Adding a `group` attribute causes a bean of type `Collection` to be registered with the context with the group name. -##### [](#receiving-batch)@RabbitListener with Batching +##### @RabbitListener with Batching When receiving a [a batch](#template-batching) of messages, the de-batching is normally performed by the container and the listener is invoked with one message at at time. Starting with version 2.2, you can configure the listener container factory and listener to receive the entire batch in one call, simply set the factory’s `batchListener` property, and make the method payload parameter a `List`: @@ -3160,7 +3160,7 @@ public void consumerBatch3(List strings) { You can also add a `Channel` parameter, often used when using `MANUAL` ack mode. This is not very useful with the third example because you don’t have access to the `delivery_tag` property. -##### [](#using-container-factories)Using Container Factories +##### Using Container Factories Listener container factories were introduced to support the `@RabbitListener` and registering containers with the `RabbitListenerEndpointRegistry`, as discussed in [Programmatic Endpoint Registration](#async-annotation-driven-registration). @@ -3210,7 +3210,7 @@ These techniques are useful if you wish to create several containers with simila | |Containers created this way are normal `@Bean` instances and are not registered in the `RabbitListenerEndpointRegistry`.| |---|------------------------------------------------------------------------------------------------------------------------| -##### [](#async-returns)Asynchronous `@RabbitListener` Return Types +##### Asynchronous `@RabbitListener` Return Types Starting with version 2.1, `@RabbitListener` (and `@RabbitHandler`) methods can be specified with asynchronous return types `ListenableFuture` and `Mono`, letting the reply be sent asynchronously. @@ -3220,7 +3220,7 @@ Starting with version 2.1, `@RabbitListener` (and `@RabbitHandler`) methods can Starting with versions 2.2.21, 2.3.13, 2.4.1, the `AcknowledgeMode` will be automatically set the `MANUAL` when async return types are detected. In addition, incoming messages with fatal exceptions will be negatively acknowledged individually, previously any prior unacknowledged message were also negatively acknowledged. -##### [](#threading)Threading and Asynchronous Consumers +##### Threading and Asynchronous Consumers A number of different threads are involved with asynchronous consumers. @@ -3244,7 +3244,7 @@ If you have a large number of factories or are using `CacheMode.CONNECTION`, you The `RabbitMQ client` uses a `ThreadFactory` to create threads for low-level I/O (socket) operations. To modify this factory, you need to configure the underlying RabbitMQ `ConnectionFactory`, as discussed in [Configuring the Underlying Client Connection Factory](#connection-factory). -##### [](#choose-container)Choosing a Container +##### Choosing a Container Version 2.0 introduced the `DirectMessageListenerContainer` (DMLC). Previously, only the `SimpleMessageListenerContainer` (SMLC) was available. @@ -3283,7 +3283,7 @@ However, the DMLC has the following benefits over the SMLC: See [Message Listener Container Configuration](#containerAttributes) for information about which configuration properties apply to each container. -##### [](#idle-containers)Detecting Idle Asynchronous Consumers +##### Detecting Idle Asynchronous Consumers While efficient, one problem with asynchronous consumers is detecting when they are idle — users might want to take some action if no messages arrive for some period of time. @@ -3328,7 +3328,7 @@ public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory() { In each of these cases, an event is published once per minute while the container is idle. -###### [](#event-consumption)Event Consumption +###### Event Consumption You can capture idle events by implementing `ApplicationListener` — either a general listener, or one narrowed to only receive this specific event. @@ -3373,7 +3373,7 @@ public class Listener { | |If you wish to use the idle event to stop the lister container, you should not call `container.stop()` on the thread that calls the listener.
Doing so always causes delays and unnecessary log messages.
Instead, you should hand off the event to a different thread that can then stop the container.| |---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#micrometer)Monitoring Listener Performance +##### Monitoring Listener Performance Starting with version 2.2, the listener containers will automatically create and update Micrometer `Timer` s for the listener, if `Micrometer` is detected on the class path, and a `MeterRegistry` is present in the application context. The timers can be disabled by setting the container property `micrometerEnabled` to `false`. @@ -3393,7 +3393,7 @@ The timers are named `spring.rabbitmq.listener` and have the following tags: You can add additional tags using the `micrometerTags` container property. -#### [](#containers-and-broker-named-queues)4.1.7. Containers and Broker-Named queues +#### 4.1.7. Containers and Broker-Named queues While it is preferable to use `AnonymousQueue` instances as auto-delete queues, starting with version 2.1, you can use broker named queues with listener containers. The following example shows how to do so: @@ -3427,7 +3427,7 @@ Just setting the names is insufficient. | |When a connection is reset and a new one is established, the new queue gets a new name.
Since there is a race condition between the container restarting and the queue being re-declared, it is important to set the container’s `missingQueuesFatal` property to `false`, since the container is likely to initially try to reconnect to the old queue.| |---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#message-converters)4.1.8. Message Converters +#### 4.1.8. Message Converters The `AmqpTemplate` also defines several methods for sending and receiving messages that delegate to a `MessageConverter`. The `MessageConverter` provides a single method for each direction: one for converting **to** a `Message` and another for converting **from** a `Message`. @@ -3480,13 +3480,13 @@ Object receiveAndConvert(String queueName) throws AmqpException; | |The `MessageListenerAdapter` mentioned in [Asynchronous Consumer](#async-consumer) also uses a `MessageConverter`.| |---|------------------------------------------------------------------------------------------------------------------| -##### [](#simple-message-converter)`SimpleMessageConverter` +##### `SimpleMessageConverter` The default implementation of the `MessageConverter` strategy is called `SimpleMessageConverter`. This is the converter that is used by an instance of `RabbitTemplate` if you do not explicitly configure an alternative. It handles text-based content, serialized Java objects, and byte arrays. -###### [](#converting-from-a-message)Converting From a `Message` +###### Converting From a `Message` If the content type of the input `Message` begins with "text" (for example, "text/plain"), it also checks for the content-encoding property to determine the charset to be used when converting the `Message` body byte array to a Java `String`. @@ -3503,19 +3503,19 @@ For all other content-types, the `SimpleMessageConverter` returns the `Message` See [Java Deserialization](#java-deserialization) for important information. -###### [](#converting-to-a-message)Converting To a `Message` +###### Converting To a `Message` When converting to a `Message` from an arbitrary Java Object, the `SimpleMessageConverter` likewise deals with byte arrays, strings, and serializable instances. It converts each of these to bytes (in the case of byte arrays, there is nothing to convert), and it ses the content-type property accordingly. If the `Object` to be converted does not match one of those types, the `Message` body is null. -##### [](#serializer-message-converter)`SerializerMessageConverter` +##### `SerializerMessageConverter` This converter is similar to the `SimpleMessageConverter` except that it can be configured with other Spring Framework`Serializer` and `Deserializer` implementations for `application/x-java-serialized-object` conversions. See [Java Deserialization](#java-deserialization) for important information. -##### [](#json-message-converter)Jackson2JsonMessageConverter +##### Jackson2JsonMessageConverter This section covers using the `Jackson2JsonMessageConverter` to convert to and from a `Message`. It has the following sections: @@ -3524,7 +3524,7 @@ It has the following sections: * [Converting from a `Message`](#Jackson2JsonMessageConverter-from-message) -###### [](#Jackson2JsonMessageConverter-to-message)Converting to a `Message` +###### Converting to a `Message` As mentioned in the previous section, relying on Java serialization is generally not recommended. One rather common alternative that is more flexible and portable across different languages and platforms is JSON @@ -3586,7 +3586,7 @@ public DefaultClassMapper classMapper() { Now, if the sending system sets the header to `thing1`, the converter creates a `Thing1` object, and so on. See the [Receiving JSON from Non-Spring Applications](#spring-rabbit-json) sample application for a complete discussion about converting messages from non-Spring applications. -###### [](#Jackson2JsonMessageConverter-from-message)Converting from a `Message` +###### Converting from a `Message` Inbound messages are converted to objects according to the type information added to headers by the sending system. @@ -3637,7 +3637,7 @@ the JSON to. | |Starting with version 1.6.11, `Jackson2JsonMessageConverter` and, therefore, `DefaultJackson2JavaTypeMapper` (`DefaultClassMapper`) provide the `trustedPackages` option to overcome [Serialization Gadgets](https://pivotal.io/security/cve-2017-4995) vulnerability.
By default and for backward compatibility, the `Jackson2JsonMessageConverter` trusts all packages — that is, it uses `*` for the option.| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -###### [](#jackson-abstract)Deserializing Abstract Classes +###### Deserializing Abstract Classes Prior to version 2.2.8, if the inferred type of a `@RabbitListener` was an abstract class (including interfaces), the converter would fall back to looking for type information in the headers and, if present, used that information; if that was not present, it would try to create the abstract class. This caused a problem when a custom `ObjectMapper` that is configured with a custom deserializer to handle the abstract class is used, but the incoming message has invalid type headers. @@ -3645,7 +3645,7 @@ This caused a problem when a custom `ObjectMapper` that is configured with a cus Starting with version 2.2.8, the previous behavior is retained by default. If you have such a custom `ObjectMapper` and you want to ignore type headers, and always use the inferred type for conversion, set the `alwaysConvertToInferredType` to `true`. This is needed for backwards compatibility and to avoid the overhead of an attempted conversion when it would fail (with a standard `ObjectMapper`). -###### [](#data-projection)Using Spring Data Projection Interfaces +###### Using Spring Data Projection Interfaces Starting with version 2.2, you can convert JSON to a Spring Data Projection interface instead of a concrete type. This allows very selective, and low-coupled bindings to data, including the lookup of values from multiple places inside the JSON document. @@ -3676,7 +3676,7 @@ You must also add `spring-data:spring-data-commons` and `com.jayway.jsonpath:jso When used as the parameter to a `@RabbitListener` method, the interface type is automatically passed to the converter as normal. -###### [](#json-complex)Converting From a `Message` With `RabbitTemplate` +###### Converting From a `Message` With `RabbitTemplate` As mentioned earlier, type information is conveyed in message headers to assist the converter when converting from a message. This works fine in most cases. @@ -3692,7 +3692,7 @@ Thing1> thing1 = | |Starting with version 2.1, the `AbstractJsonMessageConverter` class has been removed.
It is no longer the base class for `Jackson2JsonMessageConverter`.
It has been replaced by `AbstractJackson2MessageConverter`.| |---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#marshallingmessageconverter)`MarshallingMessageConverter` +##### `MarshallingMessageConverter` Yet another option is the `MarshallingMessageConverter`. It delegates to the Spring OXM library’s implementations of the `Marshaller` and `Unmarshaller` strategy interfaces. @@ -3711,7 +3711,7 @@ The following example shows how to configure a `MarshallingMessageConverter`: ``` -##### [](#jackson2xml)`Jackson2XmlMessageConverter` +##### `Jackson2XmlMessageConverter` This class was introduced in version 2.1 and can be used to convert messages from and to XML. @@ -3741,7 +3741,7 @@ See [Jackson2JsonMessageConverter](#json-message-converter) for more information | |Starting with version 2.2, `application/xml` is assumed if there is no `contentType` property, or it has the default value `application/octet-stream`.
To revert to the previous behavior (return an unconverted `byte[]`), set the converter’s `assumeSupportedContentType` property to `false`.| |---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#contenttypedelegatingmessageconverter)`ContentTypeDelegatingMessageConverter` +##### `ContentTypeDelegatingMessageConverter` This class was introduced in version 1.4.2 and allows delegation to a specific `MessageConverter` based on the content type property in the `MessageProperties`. By default, it delegates to a `SimpleMessageConverter` if there is no `contentType` property or there is a value that matches none of the configured converters. @@ -3758,14 +3758,14 @@ The following example configures a `ContentTypeDelegatingMessageConverter`: ``` -##### [](#java-deserialization)Java Deserialization +##### Java Deserialization This section covers how to deserialize Java objects. | |There is a possible vulnerability when deserializing java objects from untrusted sources.

If you accept messages from untrusted sources with a `content-type` of `application/x-java-serialized-object`, you should
consider configuring which packages and classes are allowed to be deserialized.
This applies to both the `SimpleMessageConverter` and `SerializerMessageConverter` when it is configured to use a`DefaultDeserializer` either implicitly or via configuration.

By default, the allowed list is empty, meaning all classes are deserialized.

You can set a list of patterns, such as `thing1.`**, `thing1.thing2.Cat` or ``**`.MySafeClass`.

The patterns are checked in order until a match is found.
If there is no match, a `SecurityException` is thrown.

You can set the patterns using the `allowedListPatterns` property on these converters.| |---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#message-properties-converters)Message Properties Converters +##### Message Properties Converters The `MessagePropertiesConverter` strategy interface is used to convert between the Rabbit Client `BasicProperties` and Spring AMQP `MessageProperties`. The default implementation (`DefaultMessagePropertiesConverter`) is usually sufficient for most purposes, but you can implement your own if needed. @@ -3830,7 +3830,7 @@ These changes are to avoid unexpected propagation of these properties if the sam Starting with version 2.2, the `DefaultMessagePropertiesConverter` converts any custom headers with values of type `Class` using `getName()` instead of `toString()`; this avoids consuming application having to parse the class name out of the `toString()` representation. For rolling upgrades, you may need to change your consumers to understand both formats until all producers are upgraded. -#### [](#post-processing)4.1.9. Modifying Messages - Compression and More +#### 4.1.9. Modifying Messages - Compression and More A number of extension points exist. They let you perform some processing on a message, either before it is sent to RabbitMQ or immediately after it is received. @@ -3858,7 +3858,7 @@ Also there are methods provided to remove the post processors. Similarly, `AbstractMessageListenerContainer` also has `addAfterReceivePostProcessors()` and `removeAfterReceivePostProcessor()` methods added. See the Javadoc of `RabbitTemplate` and `AbstractMessageListenerContainer` for more detail. -#### [](#request-reply)4.1.10. Request/Reply Messaging +#### 4.1.10. Request/Reply Messaging The `AmqpTemplate` also provides a variety of `sendAndReceive` methods that accept the same argument options that were described earlier for the one-way send operations (`exchange`, `routingKey`, and `Message`). Those methods are quite useful for request-reply scenarios, since they handle the configuration of the necessary `reply-to` property before sending and can listen for the reply message on an exclusive queue that is created internally for that purpose. @@ -3878,7 +3878,7 @@ See [Converting From a `Message` With `RabbitTemplate`](#json-complex) for more Starting with version 2.1, you can configure the `RabbitTemplate` with the `noLocalReplyConsumer` option to control a `noLocal` flag for reply consumers. This is `false` by default. -##### [](#reply-timeout)Reply Timeout +##### Reply Timeout By default, the send and receive methods timeout after five seconds and return null. You can modify this behavior by setting the `replyTimeout` property. @@ -3894,7 +3894,7 @@ Starting with versions 2.0.11 and 2.1.3, when you use the default `DirectReplyTo This error handler is invoked for any failed deliveries, such as late replies and messages received without a correlation header. The exception passed in is a `ListenerExecutionFailedException`, which has a `failedMessage` property. -##### [](#direct-reply-to)RabbitMQ Direct reply-to +##### RabbitMQ Direct reply-to | |Starting with version 3.4.0, the RabbitMQ server supports [direct reply-to](https://www.rabbitmq.com/direct-reply-to.html).
This eliminates the main reason for a fixed reply queue (to avoid the need to create a temporary queue for each request).
Starting with Spring AMQP version 1.4.1 direct reply-to is used by default (if supported by the server) instead of creating temporary reply queues.
When no `replyQueue` is provided (or it is set with a name of `amq.rabbitmq.reply-to`), the `RabbitTemplate` automatically detects whether direct reply-to is supported and either uses it or falls back to using a temporary reply queue.
When using direct reply-to, a `reply-listener` is not required and should not be configured.| |---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| @@ -3920,7 +3920,7 @@ Starting with version 2.3.7, the template has a new property `useChannelForCorre When this is `true`, the server does not have to copy the correlation id from the request message headers to the reply message. Instead, the channel used to send the request is used to correlate the reply to the request. -##### [](#message-correlation-with-a-reply-queue)Message Correlation With A Reply Queue +##### Message Correlation With A Reply Queue When using a fixed reply queue (other than `amq.rabbitmq.reply-to`), you must provide correlation data so that replies can be correlated to requests. See [RabbitMQ Remote Procedure Call (RPC)](https://www.rabbitmq.com/tutorials/tutorial-six-java.html). @@ -3938,7 +3938,7 @@ If you wish to use your own correlation ID, set the `RabbitTemplate` instance’ | |The correlation ID must be unique to avoid the possibility of a wrong reply being returned for a request.| |---|---------------------------------------------------------------------------------------------------------| -##### [](#reply-listener)Reply Listener Container +##### Reply Listener Container When using RabbitMQ versions prior to 3.4.0, a new temporary queue is used for each reply. However, a single reply queue can be configured on the template, which can be more efficient and also lets you set arguments on that queue. @@ -4047,7 +4047,7 @@ To do so, bind a queue to the configured dead letter exchange with a routing key See the [RabbitMQ Dead Letter Documentation](https://www.rabbitmq.com/dlx.html) for more information about configuring dead lettering. You can also take a look at the `FixedReplyQueueDeadLetterTests` test case for an example. -##### [](#async-template)Async Rabbit Template +##### Async Rabbit Template Version 1.6 introduced the `AsyncRabbitTemplate`. This has similar `sendAndReceive` (and `convertSendAndReceive`) methods to those on the [`AmqpTemplate`](#amqp-template). @@ -4138,7 +4138,7 @@ Version 2.0 introduced variants of these methods (`convertSendAndReceiveAsType`) You must configure the underlying `RabbitTemplate` with a `SmartMessageConverter`. See [Converting From a `Message` With `RabbitTemplate`](#json-complex) for more information. -##### [](#remoting)Spring Remoting with AMQP +##### Spring Remoting with AMQP | |This feature is deprecated and will be removed in 3.0.
It has been superseded for a long time by [Handling Exceptions](#annotation-error-handling) with the `returnExceptions` being set to true, and configuring a `RemoteInvocationAwareMessageConverterAdapter` on the sending side.
See [Handling Exceptions](#annotation-error-handling) for more information.| |---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| @@ -4212,7 +4212,7 @@ The following listing shows sample client and server configurations: | |By default, if the request message cannot be delivered, the calling thread eventually times out and a `RemoteProxyFailureException` is thrown.
By default, the timeout is five seconds.
You can modify that duration by setting the `replyTimeout` property on the `RabbitTemplate`.
Starting with version 1.5, by setting the `mandatory` property to `true` and enabling returns on the connection factory (see [Publisher Confirms and Returns](#cf-pub-conf-ret)), the calling thread throws an `AmqpMessageReturnedException`.
See [Reply Timeout](#reply-timeout) for more information.| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#broker-configuration)4.1.11. Configuring the Broker +#### 4.1.11. Configuring the Broker The AMQP specification describes how the protocol can be used to configure queues, exchanges, and bindings on the broker. These operations (which are portable from the 0.8 specification and higher) are present in the `AmqpAdmin` interface in the `org.springframework.amqp.core` package. @@ -4406,7 +4406,7 @@ Now, this property takes effect on any exception, including `TimeoutException` a In addition, any declaration exceptions result in the publishing of a `DeclarationExceptionEvent`, which is an `ApplicationEvent` that can be consumed by any `ApplicationListener` in the context. The event contains a reference to the admin, the element that was being declared, and the `Throwable`. -##### [](#headers-exchange)Headers Exchange +##### Headers Exchange Starting with version 1.3, you can configure the `HeadersExchange` to match on multiple headers. You can also specify whether any or all headers must match. @@ -4524,7 +4524,7 @@ public class RabbitClientConfiguration extends AbstractStockAppRabbitConfigurati The client declares another queue through the `declareQueue()` method on the `AmqpAdmin`. It binds that queue to the market data exchange with a routing pattern that is externalized in a properties file. -##### [](#builder-api)Builder API for Queues and Exchanges +##### Builder API for Queues and Exchanges Version 1.6 introduces a convenient fluent API for configuring `Queue` and `Exchange` objects when using Java configuration. The following example shows how to use it: @@ -4584,7 +4584,7 @@ public DirectExchange ex() { } ``` -##### [](#collection-declaration)Declaring Collections of Exchanges, Queues, and Bindings +##### Declaring Collections of Exchanges, Queues, and Bindings You can wrap collections of `Declarable` objects (`Queue`, `Exchange`, and `Binding`) in `Declarables` objects. The `RabbitAdmin` detects such beans (as well as discrete `Declarable` beans) in the application context, and declares the contained objects on the broker whenever a connection is established (initially and after a connection failure). @@ -4673,7 +4673,7 @@ public SimpleMessageListenerContainer container(ConnectionFactory connectionFact } ``` -##### [](#conditional-declaration)Conditional Declaration +##### Conditional Declaration By default, all queues, exchanges, and bindings are declared by all `RabbitAdmin` instances (assuming they have `auto-startup="true"`) in the application context. @@ -4748,7 +4748,7 @@ public Binding binding() { } ``` -##### [](#note-id-name)A Note On the `id` and `name` Attributes +##### A Note On the `id` and `name` Attributes The `name` attribute on `` and `` elements reflects the name of the entity in the broker. For queues, if the `name` is omitted, an anonymous queue is created (see [`AnonymousQueue`](#anonymous-queue)). @@ -4768,7 +4768,7 @@ There is no change if the element has only a `name` attribute. The bean can still be referenced by the `name` — for example, in binding declarations. However, you still cannot reference it if the name contains SpEL — you must provide an `id` for reference purposes. -##### [](#anonymous-queue)`AnonymousQueue` +##### `AnonymousQueue` In general, when you need a uniquely-named, exclusive, auto-delete queue, we recommend that you use the `AnonymousQueue`instead of broker-defined queue names (using `""` as a `Queue` name causes the broker to generate the queue name). @@ -4846,7 +4846,7 @@ Starting with version 2.1, anonymous queues are declared with argument `Queue.X_ This ensures that the queue is declared on the node to which the application is connected. You can revert to the previous behavior by calling `queue.setLeaderLocator(null)` after constructing the instance. -##### [](#declarable-recovery)Recovering Auto-Delete Declarations +##### Recovering Auto-Delete Declarations Normally, the `RabbitAdmin` (s) only recover queues/exchanges/bindings that are declared as beans in the application context; if any such declarations are auto-delete, they will be removed by the broker if the connection is lost. When the connection is re-established, the admin will redeclare the entities. @@ -4859,7 +4859,7 @@ Associated bindings are removed from the recoverable entities when queues and ex Finally, calling `resetAllManualDeclarations()` will prevent the recovery of any previously declared entities. -#### [](#broker-events)4.1.12. Broker Event Listener +#### 4.1.12. Broker Event Listener When the [Event Exchange Plugin](https://www.rabbitmq.com/event-exchange.html) is enabled, if you add a bean of type `BrokerEventListener` to the application context, it publishes selected broker events as `BrokerEvent` instances, which can be consumed with a normal Spring `ApplicationListener` or `@EventListener` method. Events are published by the broker to a topic exchange `amq.rabbitmq.event` with a different routing key for each event type. @@ -4882,7 +4882,7 @@ public void listener(BrokerEvent event) { } ``` -#### [](#delayed-message-exchange)4.1.13. Delayed Message Exchange +#### 4.1.13. Delayed Message Exchange Version 1.6 introduces support for the[Delayed Message Exchange Plugin](https://www.rabbitmq.com/blog/2015/04/16/scheduling-messages-with-rabbitmq/) @@ -4924,7 +4924,7 @@ rabbitTemplate.convertAndSend(exchange, routingKey, "foo", new MessagePostProces To check if a message was delayed, use the `getReceivedDelay()` method on the `MessageProperties`. It is a separate property to avoid unintended propagation to an output message generated from an input message. -#### [](#management-rest-api)4.1.14. RabbitMQ REST API +#### 4.1.14. RabbitMQ REST API When the management plugin is enabled, the RabbitMQ server exposes a REST API to monitor and configure the broker. A [Java Binding for the API](https://github.com/rabbitmq/hop) is now provided. @@ -4936,7 +4936,7 @@ The hop dependency (`com.rabbitmq:http-client`) is now also `optional`. See their Javadoc for more information. -#### [](#exception-handling)4.1.15. Exception Handling +#### 4.1.15. Exception Handling Many operations with the RabbitMQ Java client can throw checked exceptions. For example, there are a lot of cases where `IOException` instances may be thrown. @@ -4985,7 +4985,7 @@ You can revert to the previous behavior by setting the `discardFatalsWithXDeath` | |Starting with version 2.1.9, messages with these fatal exceptions are rejected and NOT requeued by default, even if the container acknowledge mode is MANUAL.
These exceptions generally occur before the listener is invoked so the listener does not have a chance to ack or nack the message so it remained in the queue in an un-acked state.
To revert to the previous behavior, set the `rejectManual` property on the `ConditionalRejectingErrorHandler` to `false`.| |---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#transactions)4.1.16. Transactions +#### 4.1.16. Transactions The Spring Rabbit framework has support for automatic transaction management in the synchronous and asynchronous use cases with a number of different semantics that can be selected declaratively, as is familiar to existing users of Spring transactions. This makes many if not most common messaging patterns easy to implement. @@ -5047,7 +5047,7 @@ a database constraint error or connectivity problem), the AMQP transaction is al This is sometimes known as a “Best Efforts 1 Phase Commit”, and is a very powerful pattern for reliable messaging. If the `channelTransacted` flag was set to `false` (the default) in the preceding example, the external transaction would still be provided for the listener, but all messaging operations would be auto-acked, so the effect is to commit the messaging operations even on a rollback of the business operation. -##### [](#conditional-rollback)Conditional Rollback +##### Conditional Rollback Prior to version 1.6.6, adding a rollback rule to a container’s `transactionAttribute` when using an external transaction manager (such as JDBC) had no effect. Exceptions always rolled back the transaction. @@ -5075,7 +5075,7 @@ public AbstractMessageListenerContainer container() { } ``` -##### [](#transaction-rollback)A note on Rollback of Received Messages +##### A note on Rollback of Received Messages AMQP transactions apply only to messages and acks sent to the broker. Consequently, when there is a rollback of a Spring transaction and a message has been received, Spring AMQP has to not only rollback the transaction but also manually reject the message (sort of a nack, but that is not what the specification calls it). @@ -5090,7 +5090,7 @@ For more information about RabbitMQ transactions and their limitations, see [Rab | |Previously, message requeue on transaction rollback was inconsistent between local transactions and when a `TransactionManager` was provided.
In the former case, the normal requeue logic (`AmqpRejectAndDontRequeueException` or `defaultRequeueRejected=false`) applied (see [Message Listeners and the Asynchronous Case](#async-listeners)).
With a transaction manager, the message was unconditionally requeued on rollback.
Starting with version 2.0, the behavior is consistent and the normal requeue logic is applied in both cases.
To revert to the previous behavior, you can set the container’s `alwaysRequeueWithTxManagerRollback` property to `true`.
See [Message Listener Container Configuration](#containerAttributes).| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#using-rabbittransactionmanager)Using `RabbitTransactionManager` +##### Using `RabbitTransactionManager` The [RabbitTransactionManager](https://docs.spring.io/spring-amqp/docs/latest_ga/api/org/springframework/amqp/rabbit/transaction/RabbitTransactionManager.html) is an alternative to executing Rabbit operations within, and synchronized with, external transactions. This transaction manager is an implementation of the [`PlatformTransactionManager`](https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/transaction/PlatformTransactionManager.html) interface and should be used with a single Rabbit `ConnectionFactory`. @@ -5119,7 +5119,7 @@ If you prefer XML configuration, you can declare the following bean in your XML ``` -##### [](#tx-sync)Transaction Synchronization +##### Transaction Synchronization Synchronizing a RabbitMQ transaction with some other (e.g. DBMS) transaction provides "Best Effort One Phase Commit" semantics. It is possible that the RabbitMQ transaction fails to commit during the after completion phase of transaction synchronization. @@ -5129,7 +5129,7 @@ It will simply return if no exception occurred; otherwise it will throw an `Afte Enable this feature by calling `ConnectionFactoryUtils.enableAfterCompletionFailureCapture(true)`; this is a global flag and applies to all threads. -#### [](#containerAttributes)4.1.17. Message Listener Container Configuration +#### 4.1.17. Message Listener Container Configuration There are quite a few options for configuring a `SimpleMessageListenerContainer` (SMLC) and a `DirectMessageListenerContainer` (DMLC) related to transactions and quality of service, and some of them interact with each other. Properties that apply to the SMLC, DMLC, or `StreamListenerContainer` (StLC) (see [Using the RabbitMQ Stream Plugin](#stream-support) are indicated by the check mark in the appropriate column. @@ -5142,71 +5142,71 @@ These are indicated by `N/A` for the attribute. | Property
(Attribute) | Description | SMLC | DMLC | StLC | |-----------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------|--------------------------------|--------------------------------| -| []()[`ackTimeout`](#ackTimeout)
(N/A) | When `messagesPerAck` is set, this timeout is used as an alternative to send an ack.
When a new message arrives, the count of unacked messages is compared to `messagesPerAck`, and the time since the last ack is compared to this value.
If either condition is `true`, the message is acknowledged.
When no new messages arrive and there are unacked messages, this timeout is approximate since the condition is only checked each `monitorInterval`.
See also `messagesPerAck` and `monitorInterval` in this table. | |![tickmark](images/tickmark.png)| | -| []()[`acknowledgeMode`](#acknowledgeMode)
(acknowledge) | * `NONE`: No acks are sent (incompatible with `channelTransacted=true`).
RabbitMQ calls this “autoack”, because the broker assumes all messages are acked without any action from the consumer.

* `MANUAL`: The listener must acknowledge all messages by calling `Channel.basicAck()`.

* `AUTO`: The container acknowledges the message automatically, unless the `MessageListener` throws an exception.
Note that `acknowledgeMode` is complementary to `channelTransacted` — if the channel is transacted, the broker requires a commit notification in addition to the ack.
This is the default mode.
See also `batchSize`. |![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | -| []()[`adviceChain`](#adviceChain)
(advice-chain) | An array of AOP Advice to apply to the listener execution.
This can be used to apply additional cross-cutting concerns, such as automatic retry in the event of broker death.
Note that simple re-connection after an AMQP error is handled by the `CachingConnectionFactory`, as long as the broker is still alive. |![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | -| []()[`afterReceivePostProcessors`](#afterReceivePostProcessors)
(N/A) | An array of `MessagePostProcessor` instances that are invoked before invoking the listener.
Post processors can implement `PriorityOrdered` or `Ordered`.
The array is sorted with un-ordered members invoked last.
If a post processor returns `null`, the message is discarded (and acknowledged, if appropriate). |![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | -| []()[`alwaysRequeueWithTxManagerRollback`](#alwaysRequeueWithTxManagerRollback)
(N/A) | Set to `true` to always requeue messages on rollback when a transaction manager is configured. |![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | -| []()[`autoDeclare`](#autoDeclare)
(auto-declare) | When set to `true` (default), the container uses a `RabbitAdmin` to redeclare all AMQP objects (queues, exchanges, bindings), if it detects that at least one of its queues is missing during startup, perhaps because it is an `auto-delete` or an expired queue, but the redeclaration proceeds if the queue is missing for any reason.
To disable this behavior, set this property to `false`.
Note that the container fails to start if all of its queues are missing.

| |Prior to version 1.6, if there was more than one admin in the context, the container would randomly select one.
If there were no admins, it would create one internally.
In either case, this could cause unexpected results.
Starting with version 1.6, for `autoDeclare` to work, there must be exactly one `RabbitAdmin` in the context, or a reference to a specific instance must be configured on the container using the `rabbitAdmin` property.|
|---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | +| | | +| | | +| | | +| | | +| | | +| | | | | Prior to version 1.6, if there was more than one admin in the context, the container would randomly select one.
If there were no admins, it would create one internally.
In either case, this could cause unexpected results.
Starting with version 1.6, for `autoDeclare` to work, there must be exactly one `RabbitAdmin` in the context, or a reference to a specific instance must be configured on the container using the `rabbitAdmin` property. | | | | -| []()[`autoStartup`](#autoStartup)
(auto-startup) | Flag to indicate that the container should start when the `ApplicationContext` does (as part of the `SmartLifecycle` callbacks, which happen after all beans are initialized).
Defaults to `true`, but you can set it to `false` if your broker might not be available on startup and call `start()` later manually when you know the broker is ready. |![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| -| []()[`batchSize`](#batchSize)
(transaction-size)
(batch-size) | When used with `acknowledgeMode` set to `AUTO`, the container tries to process up to this number of messages before sending an ack (waiting for each one up to the receive timeout setting).
This is also when a transactional channel is committed.
If the `prefetchCount` is less than the `batchSize`, it is increased to match the `batchSize`. |![tickmark](images/tickmark.png)| | | -| []()[`batchingStrategy`](#batchingStrategy)
(N/A) | The strategy used when debatchng messages.
Default `SimpleDebatchingStrategy`.
See [Batching](#template-batching) and [@RabbitListener with Batching](#receiving-batch). |![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | -| []()[`channelTransacted`](#channelTransacted)
(channel-transacted) | Boolean flag to signal that all messages should be acknowledged in a transaction (either manually or automatically). |![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | -| []()[`concurrency`](#concurrency)
(N/A) | `m-n` The range of concurrent consumers for each listener (min, max).
If only `n` is provided, `n` is a fixed number of consumers.
See [Listener Concurrency](#listener-concurrency). |![tickmark](images/tickmark.png)| | | -| []()[`concurrentConsumers`](#concurrentConsumers)
(concurrency) | The number of concurrent consumers to initially start for each listener.
See [Listener Concurrency](#listener-concurrency). |![tickmark](images/tickmark.png)| | | -| []()[`connectionFactory`](#connectionFactory)
(connection-factory) | A reference to the `ConnectionFactory`.
When configuring byusing the XML namespace, the default referenced bean name is `rabbitConnectionFactory`. |![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | -| []()[`consecutiveActiveTrigger`](#consecutiveActiveTrigger)
(min-consecutive-active) | The minimum number of consecutive messages received by a consumer, without a receive timeout occurring, when considering starting a new consumer.
Also impacted by 'batchSize'.
See [Listener Concurrency](#listener-concurrency).
Default: 10. |![tickmark](images/tickmark.png)| | | -| []()[`consecutiveIdleTrigger`](#consecutiveIdleTrigger)
(min-consecutive-idle) | The minimum number of receive timeouts a consumer must experience before considering stopping a consumer.
Also impacted by 'batchSize'.
See [Listener Concurrency](#listener-concurrency).
Default: 10. |![tickmark](images/tickmark.png)| | | -| []()[`consumerBatchEnabled`](#consumerBatchEnabled)
(batch-enabled) | If the `MessageListener` supports it, setting this to true enables batching of discrete messages, up to `batchSize`; a partial batch will be delivered if no new messages arrive in `receiveTimeout`.
When this is false, batching is only supported for batches created by a producer; see [Batching](#template-batching). |![tickmark](images/tickmark.png)| | | -| []()[`consumerCustomizer`](#consumerCustomizer)
(N/A) | A `ConsumerCustomizer` bean used to modify stream consumers created by the container. | | |![tickmark](images/tickmark.png)| -| []()[`consumerStartTimeout`](#consumerStartTimeout)
(N/A) | The time in milliseconds to wait for a consumer thread to start.
If this time elapses, an error log is written.
An example of when this might happen is if a configured `taskExecutor` has insufficient threads to support the container `concurrentConsumers`.

See [Threading and Asynchronous Consumers](#threading).
Default: 60000 (one minute). |![tickmark](images/tickmark.png)| | | -| []()[`consumerTagStrategy`](#consumerTagStrategy)
(consumer-tag-strategy) | Set an implementation of [ConsumerTagStrategy](#consumerTags), enabling the creation of a (unique) tag for each consumer. |![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | -| []()[`consumersPerQueue`](#consumersPerQueue)
(consumers-per-queue) | The number of consumers to create for each configured queue.
See [Listener Concurrency](#listener-concurrency). | |![tickmark](images/tickmark.png)| | -| []()[`consumeDelay`](#consumeDelay)
(N/A) | When using the [RabbitMQ Sharding Plugin](https://github.com/rabbitmq/rabbitmq-sharding) with `concurrentConsumers > 1`, there is a race condition that can prevent even distribution of the consumers across the shards.
Use this property to add a small delay between consumer starts to avoid this race condition.
You should experiment with values to determine the suitable delay for your environment. |![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | -| []()[`debatchingEnabled`](#debatchingEnabled)
(N/A) | When true, the listener container will debatch batched messages and invoke the listener with each message from the batch.
Starting with version 2.2.7, [producer created batches](#template-batching) will be debatched as a `List` if the listener is a `BatchMessageListener` or `ChannelAwareBatchMessageListener`.
Otherwise messages from the batch are presented one-at-a-time.
Default true.
See [Batching](#template-batching) and [@RabbitListener with Batching](#receiving-batch). |![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | -| []()[`declarationRetries`](#declarationRetries)
(declaration-retries) | The number of retry attempts when passive queue declaration fails.
Passive queue declaration occurs when the consumer starts or, when consuming from multiple queues, when not all queues were available during initialization.
When none of the configured queues can be passively declared (for any reason) after the retries are exhausted, the container behavior is controlled by the 'missingQueuesFatal` property, described earlier.
Default: Three retries (for a total of four attempts). |![tickmark](images/tickmark.png)| | | -| []()[`defaultRequeueRejected`](#defaultRequeueRejected)
(requeue-rejected) | Determines whether messages that are rejected because the listener threw an exception should be requeued or not.
Default: `true`. |![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | -| []()[`errorHandler`](#errorHandler)
(error-handler) | A reference to an `ErrorHandler` strategy for handling any uncaught exceptions that may occur during the execution of the MessageListener.
Default: `ConditionalRejectingErrorHandler` |![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | -| []()[`exclusive`](#exclusive)
(exclusive) | Determines whether the single consumer in this container has exclusive access to the queues.
The concurrency of the container must be 1 when this is `true`.
If another consumer has exclusive access, the container tries to recover the consumer, according to the`recovery-interval` or `recovery-back-off`.
When using the namespace, this attribute appears on the `` element along with the queue names.
Default: `false`. |![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | -| []()[`exclusiveConsumerExceptionLogger`](#exclusiveConsumerExceptionLogger)
(N/A) | An exception logger used when an exclusive consumer cannot gain access to a queue.
By default, this is logged at the `WARN` level. |![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | -| []()[`failedDeclarationRetryInterval`](#failedDeclarationRetryInterval)
(failed-declaration
-retry-interval) | The interval between passive queue declaration retry attempts.
Passive queue declaration occurs when the consumer starts or, when consuming from multiple queues, when not all queues were available during initialization.
Default: 5000 (five seconds). |![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | -| []()[`forceCloseChannel`](#forceCloseChannel)
(N/A) | If the consumers do not respond to a shutdown within `shutdownTimeout`, if this is `true`, the channel will be closed, causing any unacked messages to be requeued.
Defaults to `true` since 2.0.
You can set it to `false` to revert to the previous behavior. |![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | -| []()[`globalQos`](#globalQos)
(global-qos) | When true, the `prefetchCount` is applied globally to the channel rather than to each consumer on the channel.
See [`basicQos.global`](https://www.rabbitmq.com/amqp-0-9-1-reference.html#basic.qos.global) for more information. |![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | +| | +| | | | +| | | +| | | +| | | | +| | | | +| | | +| | | | +| | | | +| | | | +| | +| | | | +| | | +| | | +| | | +| | | +| | | | +| | | +| | | +| | | +| | | +| | | +| | | +| | | | (group) | This is available only when using the namespace.
When specified, a bean of type `Collection` is registered with this name, and the
container for each `` element is added to the collection.
This allows, for example, starting and stopping the group of containers by iterating over the collection.
If multiple `` elements have the same group value, the containers in the collection form
an aggregate of all containers so designated. |![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | -| []()[`idleEventInterval`](#idleEventInterval)
(idle-event-interval) | See [Detecting Idle Asynchronous Consumers](#idle-containers). |![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | -| []()[`javaLangErrorHandler`](#javaLangErrorHandler)
(N/A) | An `AbstractMessageListenerContainer.JavaLangErrorHandler` implementation that is called when a container thread catches an `Error`.
The default implementation calls `System.exit(99)`; to revert to the previous behavior (do nothing), add a no-op handler. |![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | -| []()[`maxConcurrentConsumers`](#maxConcurrentConsumers)
(max-concurrency) | The maximum number of concurrent consumers to start, if needed, on demand.
Must be greater than or equal to 'concurrentConsumers'.
See [Listener Concurrency](#listener-concurrency). |![tickmark](images/tickmark.png)| | | -| []()[`messagesPerAck`](#messagesPerAck)
(N/A) | The number of messages to receive between acks.
Use this to reduce the number of acks sent to the broker (at the cost of increasing the possibility of redelivered messages).
Generally, you should set this property only on high-volume listener containers.
If this is set and a message is rejected (exception thrown), pending acks are acknowledged and the failed message is rejected.
Not allowed with transacted channels.
If the `prefetchCount` is less than the `messagesPerAck`, it is increased to match the `messagesPerAck`.
Default: ack every message.
See also `ackTimeout` in this table. | |![tickmark](images/tickmark.png)| | -| []()[`mismatchedQueuesFatal`](#mismatchedQueuesFatal)
(mismatched-queues-fatal) |When the container starts, if this property is `true` (default: `false`), the container checks that all queues declared in the context are compatible with queues already on the broker.
If mismatched properties (such as `auto-delete`) or arguments (skuch as `x-message-ttl`) exist, the container (and application context) fails to start with a fatal exception.

If the problem is detected during recovery (for example, after a lost connection), the container is stopped.

There must be a single `RabbitAdmin` in the application context (or one specifically configured on the container by using the `rabbitAdmin` property).
Otherwise, this property must be `false`.

| |If the broker is not available during initial startup, the container starts and the conditions are checked when the connection is established.|
|---|----------------------------------------------------------------------------------------------------------------------------------------------|

| |The check is done against all queues in the context, not just the queues that a particular listener is configured to use.
If you wish to limit the checks to just those queues used by a container, you should configure a separate `RabbitAdmin` for the container, and provide a reference to it using the `rabbitAdmin` property.
See [Conditional Declaration](#conditional-declaration) for more information.|
|---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

| |Mismatched queue argument detection is disabled while starting a container for a `@RabbitListener` in a bean that is marked `@Lazy`.
This is to avoid a potential deadlock which can delay the start of such containers for up to 60 seconds.
Applications using lazy listener beans should check the queue arguments before getting a reference to the lazy bean.|
|---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------||![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | +| | | +| | | +| | | | +| | | +| | | | | If the broker is not available during initial startup, the container starts and the conditions are checked when the connection is established. | | | | | | The check is done against all queues in the context, not just the queues that a particular listener is configured to use.
If you wish to limit the checks to just those queues used by a container, you should configure a separate `RabbitAdmin` for the container, and provide a reference to it using the `rabbitAdmin` property.
See [Conditional Declaration](#conditional-declaration) for more information. | | | | | | Mismatched queue argument detection is disabled while starting a container for a `@RabbitListener` in a bean that is marked `@Lazy`.
This is to avoid a potential deadlock which can delay the start of such containers for up to 60 seconds.
Applications using lazy listener beans should check the queue arguments before getting a reference to the lazy bean. | | | | -| []()[`missingQueuesFatal`](#missingQueuesFatal)
(missing-queues-fatal) | When set to `true` (default), if none of the configured queues are available on the broker, it is considered fatal.
This causes the application context to fail to initialize during startup.
Also, when the queues are deleted while the container is running, by default, the consumers make three retries to connect to the queues (at five second intervals) and stop the container if these attempts fail.

This was not configurable in previous versions.

When set to `false`, after making the three retries, the container goes into recovery mode, as with other problems, such as the broker being down.
The container tries to recover according to the `recoveryInterval` property.
During each recovery attempt, each consumer again tries four times to passively declare the queues at five second intervals.
This process continues indefinitely.

You can also use a properties bean to set the property globally for all containers, as follows:

```
id="spring.amqp.global.properties">

false


```

This global property is not applied to any containers that have an explicit `missingQueuesFatal` property set.

The default retry properties (three retries at five-second intervals) can be overridden by setting the properties below.

| |Missing queue detection is disabled while starting a container for a `@RabbitListener` in a bean that is marked `@Lazy`.
This is to avoid a potential deadlock which can delay the start of such containers for up to 60 seconds.
Applications using lazy listener beans should check the queue(s) before getting a reference to the lazy bean.|
|---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | +| | | | | Missing queue detection is disabled while starting a container for a `@RabbitListener` in a bean that is marked `@Lazy`.
This is to avoid a potential deadlock which can delay the start of such containers for up to 60 seconds.
Applications using lazy listener beans should check the queue(s) before getting a reference to the lazy bean. | | | | -| []()[`monitorInterval`](#monitorInterval)
(monitor-interval) | With the DMLC, a task is scheduled to run at this interval to monitor the state of the consumers and recover any that have failed. | |![tickmark](images/tickmark.png)| | -| []()[`noLocal`](#noLocal)
(N/A) | Set to `true` to disable delivery from the server to consumers messages published on the same channel’s connection. |![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | -| []()[`phase`](#phase)
(phase) | When `autoStartup` is `true`, the lifecycle phase within which this container should start and stop.
The lower the value, the earlier this container starts and the later it stops.
The default is `Integer.MAX_VALUE`, meaning the container starts as late as possible and stops as soon as possible. |![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | -|[]()[`possibleAuthenticationFailureFatal`](#possibleAuthenticationFailureFatal)
(possible-authentication-failure-fatal)| When set to `true` (default for SMLC), if a `PossibleAuthenticationFailureException` is thrown during connection, it is considered fatal.
This causes the application context to fail to initialize during startup (if the container is configured with auto startup).

Since *version 2.0*.

**DirectMessageListenerContainer**

When set to `false` (default), each consumer will attempt to reconnect according to the `monitorInterval`.

**SimpleMessageListenerContainer**

When set to `false`, after making the 3 retries, the container will go into recovery mode, as with other problems, such as the broker being down.
The container will attempt to recover according to the `recoveryInterval` property.
During each recovery attempt, each consumer will again try 4 times to start.
This process will continue indefinitely.

You can also use a properties bean to set the property globally for all containers, as follows:

```
id="spring.amqp.global.properties">
key="mlc.possible.authentication.failure.fatal">
false


```

This global property will not be applied to any containers that have an explicit `missingQueuesFatal` property set.

The default retry properties (3 retries at 5 second intervals) can be overridden using the properties after this one. |![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | -| []()[`prefetchCount`](#prefetchCount)
(prefetch) | The number of unacknowledged messages that can be outstanding at each consumer.
The higher this value is, the faster the messages can be delivered, but the higher the risk of non-sequential processing.
Ignored if the `acknowledgeMode` is `NONE`.
This is increased, if necessary, to match the `batchSize` or `messagePerAck`.
Defaults to 250 since 2.0.
You can set it to 1 to revert to the previous behavior.

| |There are scenarios where the prefetch value should
be low — for example, with large messages, especially if the processing is slow (messages could add up
to a large amount of memory in the client process), and if strict message ordering is necessary
(the prefetch value should be set back to 1 in this case).
Also, with low-volume messaging and multiple consumers (including concurrency within a single listener container instance), you may wish to reduce the prefetch to get a more even distribution of messages across consumers.|
|---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

Also see `globalQos`. |![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | +| | | +| | | +| | | +|| | +| | | | | There are scenarios where the prefetch value should
be low — for example, with large messages, especially if the processing is slow (messages could add up
to a large amount of memory in the client process), and if strict message ordering is necessary
(the prefetch value should be set back to 1 in this case).
Also, with low-volume messaging and multiple consumers (including concurrency within a single listener container instance), you may wish to reduce the prefetch to get a more even distribution of messages across consumers. | | | | -| []()[`rabbitAdmin`](#rabbitAdmin)
(admin) | When a listener container listens to at least one auto-delete queue and it is found to be missing during startup, the container uses a `RabbitAdmin` to declare the queue and any related bindings and exchanges.
If such elements are configured to use conditional declaration (see [Conditional Declaration](#conditional-declaration)), the container must use the admin that was configured to declare those elements.
Specify that admin here.
It is required only when using auto-delete queues with conditional declaration.
If you do not wish the auto-delete queues to be declared until the container is started, set `auto-startup` to `false` on the admin.
Defaults to a `RabbitAdmin` that declares all non-conditional elements. |![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | -| []()[`receiveTimeout`](#receiveTimeout)
(receive-timeout) | The maximum time to wait for each message.
If `acknowledgeMode=NONE`, this has very little effect — the container spins round and asks for another message.
It has the biggest effect for a transactional `Channel` with `batchSize > 1`, since it can cause messages already consumed not to be acknowledged until the timeout expires.
When `consumerBatchEnabled` is true, a partial batch will be delivered if this timeout occurs before a batch is complete. |![tickmark](images/tickmark.png)| | | -| []()[`recoveryBackOff`](#recoveryBackOff)
(recovery-back-off) | Specifies the `BackOff` for intervals between attempts to start a consumer if it fails to start for non-fatal reasons.
Default is `FixedBackOff` with unlimited retries every five seconds.
Mutually exclusive with `recoveryInterval`. |![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | -| []()[`recoveryInterval`](#recoveryInterval)
(recovery-interval) | Determines the time in milliseconds between attempts to start a consumer if it fails to start for non-fatal reasons.
Default: 5000.
Mutually exclusive with `recoveryBackOff`. |![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | -| []()[`retryDeclarationInterval`](#retryDeclarationInterval)
(missing-queue-
retry-interval) | If a subset of the configured queues are available during consumer initialization, the consumer starts consuming from those queues.
The consumer tries to passively declare the missing queues by using this interval.
When this interval elapses, the 'declarationRetries' and 'failedDeclarationRetryInterval' is used again.
If there are still missing queues, the consumer again waits for this interval before trying again.
This process continues indefinitely until all queues are available.
Default: 60000 (one minute). |![tickmark](images/tickmark.png)| | | -| []()[`shutdownTimeout`](#shutdownTimeout)
(N/A) | When a container shuts down (for example,
if its enclosing `ApplicationContext` is closed), it waits for in-flight messages to be processed up to this limit.
Defaults to five seconds. |![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | -| []()[`startConsumerMinInterval`](#startConsumerMinInterval)
(min-start-interval) | The time in milliseconds that must elapse before each new consumer is started on demand.
See [Listener Concurrency](#listener-concurrency).
Default: 10000 (10 seconds). |![tickmark](images/tickmark.png)| | | -| []()[`statefulRetryFatal`](#statefulRetryFatal)
WithNullMessageId
(N/A) | When using a stateful retry advice, if a message with a missing `messageId` property is received, it is considered
fatal for the consumer (it is stopped) by default.
Set this to `false` to discard (or route to a dead-letter queue) such messages. |![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | -| []()[`stopConsumerMinInterval`](#stopConsumerMinInterval)
(min-stop-interval) | The time in milliseconds that must elapse before a consumer is stopped since the last consumer was stopped when an idle consumer is detected.
See [Listener Concurrency](#listener-concurrency).
Default: 60000 (one minute). |![tickmark](images/tickmark.png)| | | -| []()[`streamConverter`](#streamConverter)
(N/A) | A `StreamMessageConverter` to convert a native Stream message to a Spring AMQP message. | | |![tickmark](images/tickmark.png)| -| []()[`taskExecutor`](#taskExecutor)
(task-executor) | A reference to a Spring `TaskExecutor` (or standard JDK 1.5+ `Executor`) for executing listener invokers.
Default is a `SimpleAsyncTaskExecutor`, using internally managed threads. |![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | -| []()[`taskScheduler`](#taskScheduler)
(task-scheduler) | With the DMLC, the scheduler used to run the monitor task at the 'monitorInterval'. | |![tickmark](images/tickmark.png)| | -| []()[`transactionManager`](#transactionManager)
(transaction-manager) | External transaction manager for the operation of the listener.
Also complementary to `channelTransacted` — if the `Channel` is transacted, its transaction is synchronized with the external transaction. |![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | - -#### [](#listener-concurrency)4.1.18. Listener Concurrency - -##### [](#simplemessagelistenercontainer)SimpleMessageListenerContainer +| | | +| | | | +| | | +| | | +| | | | +| | | +| | | | +| | | +| | | | +| | +| | | +| | | +| | | + +#### 4.1.18. Listener Concurrency + +##### SimpleMessageListenerContainer By default, the listener container starts a single consumer that receives messages from the queues. @@ -5239,7 +5239,7 @@ Each consumer uses a single channel, regardless of the number of configured queu Starting with version 2.0, the `concurrentConsumers` and `maxConcurrentConsumers` properties can be set with the `concurrency` property — for example, `2-4`. -##### [](#using-directmessagelistenercontainer)Using `DirectMessageListenerContainer` +##### Using `DirectMessageListenerContainer` With this container, concurrency is based on the configured queues and `consumersPerQueue`. Each consumer for each queue uses a separate channel, and the concurrency is controlled by the rabbit client library. @@ -5247,7 +5247,7 @@ By default, at the time of writing, it uses a pool of `DEFAULT_NUM_THREADS = Run You can configure a `taskExecutor` to provide the required maximum concurrency. -#### [](#exclusive-consumer)4.1.19. Exclusive Consumer +#### 4.1.19. Exclusive Consumer Starting with version 1.3, you can configure the listener container with a single exclusive consumer. This prevents other containers from consuming from the queues until the current consumer is cancelled. @@ -5255,7 +5255,7 @@ The concurrency of such a container must be `1`. When using exclusive consumers, other containers try to consume from the queues according to the `recoveryInterval` property and log a `WARN` message if the attempt fails. -#### [](#listener-queues)4.1.20. Listener Container Queues +#### 4.1.20. Listener Container Queues Version 1.3 introduced a number of improvements for handling multiple queues in a listener container. @@ -5275,7 +5275,7 @@ Previously, a cancel on one queue cancelled the entire consumer and, eventually, If you wish to permanently remove a queue, you should update the container before or after deleting to queue, to avoid future attempts trying to consume from it. -#### [](#resilience-recovering-from-errors-and-broker-failures)4.1.21. Resilience: Recovering from Errors and Broker Failures +#### 4.1.21. Resilience: Recovering from Errors and Broker Failures Some of the key (and most popular) high-level features that Spring AMQP provides are to do with recovery and automatic re-connection in the event of a protocol error or broker failure. We have seen all the relevant components already in this guide, but it should help to bring them all together here and call out the features and recovery scenarios individually. @@ -5284,7 +5284,7 @@ The primary reconnection features are enabled by the `CachingConnectionFactory` It is also often beneficial to use the `RabbitAdmin` auto-declaration features. In addition, if you care about guaranteed delivery, you probably also need to use the `channelTransacted` flag in `RabbitTemplate` and `SimpleMessageListenerContainer` and the `AcknowledgeMode.AUTO` (or manual if you do the acks yourself) in the `SimpleMessageListenerContainer`. -##### [](#automatic-declaration)Automatic Declaration of Exchanges, Queues, and Bindings +##### Automatic Declaration of Exchanges, Queues, and Bindings The `RabbitAdmin` component can declare exchanges, queues, and bindings on startup. It does this lazily, through a `ConnectionListener`. @@ -5319,7 +5319,7 @@ It is also useful in projects that don’t provide direct access to the `Declara See also [RabbitMQ Automatic Connection/Topology recovery](#auto-recovery). -##### [](#retry)Failures in Synchronous Operations and Options for Retry +##### Failures in Synchronous Operations and Options for Retry If you lose your connection to the broker in a synchronous sequence when using `RabbitTemplate` (for instance), Spring AMQP throws an `AmqpException` (usually, but not always, `AmqpIOException`). We do not try to hide the fact that there was a problem, so you have to be able to catch and respond to the exception. @@ -5362,7 +5362,7 @@ Only a subset of retry capabilities can be configured this way. More advanced features would need the configuration of a `RetryTemplate` as a Spring bean. See the [Spring Retry Javadoc](https://docs.spring.io/spring-retry/docs/api/current/) for complete information about available policies and their configuration. -##### [](#batch-retry)Retry with Batch Listeners +##### Retry with Batch Listeners It is not recommended to configure retry with a batch listener, unless the batch was created by the producer, in a single record. See [Batched Messages](#de-batching) for information about consumer and producer-created batches. @@ -5372,7 +5372,7 @@ Applications may want to inform a custom recoverer where in the batch the failur A retry recoverer for a batch listener must implement `MessageBatchRecoverer`. -##### [](#async-listeners)Message Listeners and the Asynchronous Case +##### Message Listeners and the Asynchronous Case If a `MessageListener` fails because of a business exception, the exception is handled by the message listener container, which then goes back to listening for another message. If the failure is caused by a dropped connection (not a business exception), the consumer that is collecting messages for the listener has to be cancelled and restarted. @@ -5458,7 +5458,7 @@ See [Publisher Confirms and Returns](#cf-pub-conf-ret) for more information abou Starting with version 2.1, an `ImmediateRequeueMessageRecoverer` is added to throw an `ImmediateRequeueAmqpException`, which notifies a listener container to requeue the current failed message. -##### [](#exception-classification-for-spring-retry)Exception Classification for Spring Retry +##### Exception Classification for Spring Retry Spring Retry has a great deal of flexibility for determining which exceptions can invoke retry. The default configuration retries for all exceptions. @@ -5470,7 +5470,7 @@ When `true`, it travers exception causes until it finds a match or there is no c To use this classifier for retry, you can use a `SimpleRetryPolicy` created with the constructor that takes the max attempts, the `Map` of `Exception` instances, and the boolean (`traverseCauses`) and inject this policy into the `RetryTemplate`. -#### [](#multi-rabbit)4.1.22. Multiple Broker (or Cluster) Support +#### Support Version 2.3 added more convenience when communicating between a single application and multiple brokers or broker clusters. The main benefit, on the consumer side, is that the infrastructure can automatically associate auto-declared queues with the appropriate broker. @@ -5616,7 +5616,7 @@ public ApplicationRunner runner(RabbitTemplate template, ConnectionFactoryContex } ``` -#### [](#debugging)4.1.23. Debugging +#### 4.1.23. Debugging Spring AMQP provides extensive logging, especially at the `DEBUG` level. @@ -5627,7 +5627,7 @@ You can run it and change your connection factory configuration to connect to po It displays the decoded protocol on the console. Refer to the `Tracer` Javadoc for more information. -### [](#stream-support)4.2. Using the RabbitMQ Stream Plugin +### 4.2. Using the RabbitMQ Stream Plugin Version 2.4 introduces initial support for the [RabbitMQ Stream Plugin Java Client](https://github.com/rabbitmq/rabbitmq-stream-java-client) for the [RabbitMQ Stream Plugin](https://rabbitmq.com/stream.html). @@ -5635,7 +5635,7 @@ Version 2.4 introduces initial support for the [RabbitMQ Stream Plugin Java Clie * `StreamListenerContainer` -#### [](#sending-messages-2)4.2.1. Sending Messages +#### 4.2.1. Sending Messages The `RabbitStreamTemplate` provides a subset of the `RabbitTemplate` (AMQP) functionality. @@ -5692,7 +5692,7 @@ The `ProducerCustomizer` provides a mechanism to customize the producer before i Refer to the [Java Client Documentation](https://rabbitmq.github.io/rabbitmq-stream-java-client/stable/htmlsingle/) about customizing the `Environment` and `Producer`. -#### [](#receiving-messages-2)4.2.2. Receiving Messages +#### 4.2.2. Receiving Messages Asynchronous message reception is provided by the `StreamListenerContainer` (and the `StreamRabbitListenerContainerFactory` when using `@RabbitListener`). @@ -5717,7 +5717,7 @@ Refer to the [Java Client Documentation](https://rabbitmq.github.io/rabbitmq-str When using `@RabbitListener`, configure a `StreamRabbitListenerContainerFactory`; at this time, most `@RabbitListener` properties (`concurrency`, etc) are ignored. Only `id`, `queues`, `autoStartup` and `containerFactory` are supported. In addition, `queues` can only contain one stream name. -#### [](#examples)4.2.3. Examples +#### 4.2.3. Examples ``` @Bean @@ -5756,7 +5756,7 @@ void nativeMsg(Message in, Context context) { } ``` -### [](#logging)4.3. Logging Subsystem AMQP Appenders +### 4.3. Logging Subsystem AMQP Appenders The framework provides logging appenders for some popular logging subsystems: @@ -5766,7 +5766,7 @@ The framework provides logging appenders for some popular logging subsystems: The appenders are configured by using the normal mechanisms for the logging subsystem, available properties are specified in the following sections. -#### [](#common-properties)4.3.1. Common properties +#### 4.3.1. Common properties The following properties are available with all appenders: @@ -5806,7 +5806,7 @@ The following properties are available with all appenders: |```
clientConnectionProperties
```| ```
null
``` | A comma-delimited list of `key:value` pairs for custom client properties to the RabbitMQ connection. | | ```
addMdcAsHeaders
``` | ```
true
``` |MDC properties were always added into RabbitMQ message headers until this property was introduced.
It can lead to issues for big MDC as while RabbitMQ has limited buffer size for all headers and this buffer is pretty small.
This property was introduced to avoid issues in cases of big MDC.
By default this value set to `true` for backward compatibility.
The `false` turns off serialization MDC into headers.
Please note, the `JsonLayout` adds MDC into the message by default.| -#### [](#log4j-2-appender)4.3.2. Log4j 2 Appender +#### 4.3.2. Log4j 2 Appender The following example shows how to configure a Log4j 2 appender: @@ -5828,7 +5828,7 @@ The following example shows how to configure a Log4j 2 appender: | |Starting with versions 1.6.10 and 1.7.3, by default, the log4j2 appender publishes the messages to RabbitMQ on the calling thread.
This is because Log4j 2 does not, by default, create thread-safe events.
If the broker is down, the `maxSenderRetries` is used to retry, with no delay between retries.
If you wish to restore the previous behavior of publishing the messages on separate threads (`senderPoolSize`), you can set the `async` property to `true`.
However, you also need to configure Log4j 2 to use the `DefaultLogEventFactory` instead of the `ReusableLogEventFactory`.
One way to do that is to set the system property `-Dlog4j2.enable.threadlocals=false`.
If you use asynchronous publishing with the `ReusableLogEventFactory`, events have a high likelihood of being corrupted due to cross-talk.| |---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#logback-appender)4.3.3. Logback Appender +#### 4.3.3. Logback Appender The following example shows how to configure a logback appender: @@ -5859,7 +5859,7 @@ You can configure the appender to include caller data by setting the `includeCal Starting with version 2.0.0, the Logback `AmqpAppender` supports [Logback encoders](https://logback.qos.ch/manual/encoders.html) with the `encoder` option. The `encoder` and `layout` options are mutually exclusive. -#### [](#customizing-the-messages)4.3.4. Customizing the Messages +#### 4.3.4. Customizing the Messages By default, AMQP appenders populate the following message properties: @@ -5935,11 +5935,11 @@ public class MyEnhancedAppender extends AmqpAppender { } ``` -#### [](#customizing-the-client-properties)4.3.5. Customizing the Client Properties +#### 4.3.5. Customizing the Client Properties You can add custom client properties by adding either string properties or more complex properties. -##### [](#simple-string-properties)Simple String Properties +##### Simple String Properties Each appender supports adding client properties to the RabbitMQ connection. @@ -5971,7 +5971,7 @@ Keys and values cannot contain commas or colons. These properties appear on the RabbitMQ Admin UI when the connection is viewed. -##### [](#advanced-technique-for-logback)Advanced Technique for Logback +##### Advanced Technique for Logback You can subclass the Logback appender. Doing so lets you modify the client connection properties before the connection is established. @@ -5999,7 +5999,7 @@ Then you can add `thing2` to logback.xml. For String properties such as those shown in the preceding example, the previous technique can be used. Subclasses allow for adding richer properties (such as adding a `Map` or numeric property). -#### [](#providing-a-custom-queue-implementation)4.3.6. Providing a Custom Queue Implementation +#### 4.3.6. Providing a Custom Queue Implementation The `AmqpAppenders` use a `BlockingQueue` to asynchronously publish logging events to RabbitMQ. By default, a `LinkedBlockingQueue` is used. @@ -6030,7 +6030,7 @@ The Log4j 2 appender supports using a [`BlockingQueueFactory`](https://logging.a ``` -### [](#sample-apps)4.4. Sample Applications +### 4.4. Sample Applications The [Spring AMQP Samples](https://github.com/SpringSource/spring-amqp-samples) project includes two sample applications. The first is a simple “Hello World” example that demonstrates both synchronous and asynchronous message reception. @@ -6039,12 +6039,12 @@ The second sample is based on a stock-trading use case to demonstrate the types In this chapter, we provide a quick walk-through of each sample so that you can focus on the most important components. The samples are both Maven-based, so you should be able to import them directly into any Maven-aware IDE (such as [SpringSource Tool Suite](https://www.springsource.org/sts)). -#### [](#hello-world-sample)4.4.1. The “Hello World” Sample +#### 4.4.1. The “Hello World” Sample The “Hello World” sample demonstrates both synchronous and asynchronous message reception. You can import the `spring-rabbit-helloworld` sample into the IDE and then follow the discussion below. -##### [](#hello-world-sync)Synchronous Example +##### Synchronous Example Within the `src/main/java` directory, navigate to the `org.springframework.amqp.helloworld` package. Open the `HelloWorldConfiguration` class and notice that it contains the `@Configuration` annotation at the class level and notice some `@Bean` annotations at method-level. @@ -6119,7 +6119,7 @@ public static void main(String[] args) { If you run the `Producer` and then run the `Consumer`, you should see `Received: Hello World` in the console output. -##### [](#hello-world-async)Asynchronous Example +##### Asynchronous Example [Synchronous Example](#hello-world-sync) walked through the synchronous Hello World sample. This section describes a slightly more advanced but significantly more powerful option. @@ -6208,7 +6208,7 @@ If you look in the `Consumer` class, you can see that its `main()` method consis The Producer’s `main()` method is also a one-line bootstrap, since the component whose method is annotated with `@Scheduled` also starts automatically. You can start the `Producer` and `Consumer` in any order, and you should see messages being sent and received every three seconds. -#### [](#stock-trading)4.4.2. Stock Trading +#### 4.4.2. Stock Trading The Stock Trading sample demonstrates more advanced messaging scenarios than [the Hello World sample](#hello-world-sample). However, the configuration is very similar, if a bit more involved. @@ -6355,7 +6355,7 @@ If you are no longer running the server and client, start them now. Try sending a request with the format of '100 TCKR'. After a brief artificial delay that simulates “processing” of the request, you should see a confirmation message appear on the client. -#### [](#spring-rabbit-json)4.4.3. Receiving JSON from Non-Spring Applications +#### 4.4.3. Receiving JSON from Non-Spring Applications Spring applications, when sending JSON, set the `*TypeId*` header to the fully qualified class name to assist the receiving application in converting the JSON back to a Java object. @@ -6363,7 +6363,7 @@ The `spring-rabbit-json` sample explores several techniques to convert the JSON See also [Jackson2JsonMessageConverter](#json-message-converter) as well as the [Javadoc for the `DefaultClassMapper`](https://docs.spring.io/spring-amqp/docs/current/api/index.html?org/springframework/amqp/support/converter/DefaultClassMapper.html). -### [](#testing)4.5. Testing Support +### 4.5. Testing Support Writing integration for asynchronous applications is necessarily more complex than testing simpler applications. This is made more complex when abstractions such as the `@RabbitListener` annotations come into the picture. @@ -6377,7 +6377,7 @@ Spring AMQP version 1.6 introduced the `spring-rabbit-test` jar, which provides It is anticipated that this project will expand over time, but we need community feedback to make suggestions for the features needed to help with testing. Please use [JIRA](https://jira.spring.io/browse/AMQP) or [GitHub Issues](https://github.com/spring-projects/spring-amqp/issues) to provide such feedback. -#### [](#spring-rabbit-test)4.5.1. @SpringRabbitTest +#### 4.5.1. @SpringRabbitTest Use this annotation to add infrastructure beans to the Spring test `ApplicationContext`. This is not necessary when using, for example `@SpringBootTest` since Spring Boot’s auto configuration will add the beans. @@ -6427,7 +6427,7 @@ public class MyRabbitTests { With JUnit4, replace `@SpringJunitConfig` with `@RunWith(SpringRunnner.class)`. -#### [](#mockito-answer)4.5.2. Mockito `Answer` Implementations +#### 4.5.2. Mockito `Answer` Implementations There are currently two `Answer` implementations to help with testing. @@ -6482,7 +6482,7 @@ Use `answer.getExceptions()` to get a reference to them. When used in conjunction with the [`@RabbitListenerTest` and `RabbitListenerTestHarness`](#test-harness) use `harness.getLambdaAnswerFor("listenerId", true, …​)` to get a properly constructed answer for the listener. -#### [](#test-harness)4.5.3. `@RabbitListenerTest` and `RabbitListenerTestHarness` +#### 4.5.3. `@RabbitListenerTest` and `RabbitListenerTestHarness` Annotating one of your `@Configuration` classes with `@RabbitListenerTest` causes the framework to replace the standard `RabbitListenerAnnotationBeanPostProcessor` with a subclass called `RabbitListenerTestHarness` (it also enables`@RabbitListener` detection through `@EnableRabbit`). @@ -6649,7 +6649,7 @@ public class MyTests { | |When using custom `Answer` s with the harness, in order to operate properly, such answers should subclass `ForwardsInvocation` and get the actual listener (not the spy) from the harness (`getDelegate("myListener")`) and call `super.answer(invocation)`.
See the provided [Mockito `Answer` Implementations](#mockito-answer) source code for examples.| |---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#test-template)4.5.4. Using `TestRabbitTemplate` +#### 4.5.4. Using `TestRabbitTemplate` The `TestRabbitTemplate` is provided to perform some basic integration testing without the need for a broker. When you add it as a `@Bean` in your test case, it discovers all the listener containers in the context, whether declared as `@Bean` or `` or using the `@RabbitListener` annotation. @@ -6765,13 +6765,13 @@ public class TestRabbitTemplateTests { } ``` -#### [](#junit-rules)4.5.5. JUnit4 `@Rules` +#### 4.5.5. JUnit4 `@Rules` Spring AMQP version 1.7 and later provide an additional jar called `spring-rabbit-junit`. This jar contains a couple of utility `@Rule` instances for use when running JUnit4 tests. See [JUnit5 Conditions](#junit5-conditions) for JUnit5 testing. -##### [](#using-brokerrunning)Using `BrokerRunning` +##### Using `BrokerRunning` `BrokerRunning` provides a mechanism to let tests succeed when a broker is not running (on `localhost`, by default). @@ -6791,7 +6791,7 @@ public static void tearDown() { There are several `isRunning…​` static methods, such as `isBrokerAndManagementRunning()`, which verifies the broker has the management plugin enabled. -###### [](#brokerRunning-configure)Configuring the Rule +###### Configuring the Rule There are times when you want tests to fail if there is no broker, such as a nightly CI build. To disable the rule at runtime, set an environment variable called `RABBITMQ_SERVER_REQUIRED` to `true`. @@ -6847,7 +6847,7 @@ public CachingConnectionFactory rabbitConnectionFactory() { } ``` -##### [](#using-longrunningintegrationtest)Using `LongRunningIntegrationTest` +##### Using `LongRunningIntegrationTest` `LongRunningIntegrationTest` is a rule that disables long running tests. You might want to use this on a developer system but ensure that the rule is disabled on, for example, nightly CI builds. @@ -6861,11 +6861,11 @@ public LongRunningIntegrationTest longTests = new LongRunningIntegrationTest(); To disable the rule at runtime, set an environment variable called `RUN_LONG_INTEGRATION_TESTS` to `true`. -#### [](#junit5-conditions)4.5.6. JUnit5 Conditions +#### 4.5.6. JUnit5 Conditions Version 2.0.2 introduced support for JUnit5. -##### [](#using-the-rabbitavailable-annotation)Using the `@RabbitAvailable` Annotation +##### Using the `@RabbitAvailable` Annotation This class-level annotation is similar to the `BrokerRunning` `@Rule` discussed in [JUnit4 `@Rules`](#junit-rules). It is processed by the `RabbitAvailableCondition`. @@ -7006,7 +7006,7 @@ public class RabbitTemplateMPPIntegrationTests { } ``` -##### [](#using-the-longrunning-annotation)Using the `@LongRunning` Annotation +##### Using the `@LongRunning` Annotation Similar to the `LongRunningIntegrationTest` JUnit4 `@Rule`, this annotation causes tests to be skipped unless an environment variable (or system property) is set to `true`. The following example shows how to use it: @@ -7025,15 +7025,15 @@ public class SimpleMessageListenerContainerLongTests { By default, the variable is `RUN_LONG_INTEGRATION_TESTS`, but you can specify the variable name in the annotation’s `value` attribute. -## [](#spring-integration-reference)5. Spring Integration - Reference +## 5. Spring Integration - Reference This part of the reference documentation provides a quick introduction to the AMQP support within the Spring Integration project. -### [](#spring-integration-amqp)5.1. Spring Integration AMQP Support +### 5.1. Spring Integration AMQP Support This brief chapter covers the relationship between the Spring Integration and the Spring AMQP projects. -#### [](#spring-integration-amqp-introduction)5.1.1. Introduction +#### 5.1.1. Introduction The [Spring Integration](https://www.springsource.org/spring-integration) project includes AMQP Channel Adapters and Gateways that build upon the Spring AMQP project. Those adapters are developed and released in the Spring Integration project. @@ -7044,7 +7044,7 @@ Since the AMQP adapters are part of the Spring Integration release, the document We provide a quick overview of the main features here. See the [Spring Integration Reference Guide](https://docs.spring.io/spring-integration/reference/htmlsingle/) for much more detail. -#### [](#inbound-channel-adapter)5.1.2. Inbound Channel Adapter +#### 5.1.2. Inbound Channel Adapter To receive AMQP Messages from a queue, you can configure an ``. The following example shows how to configure an inbound channel adapter: @@ -7055,7 +7055,7 @@ The following example shows how to configure an inbound channel adapter: connection-factory="rabbitConnectionFactory"/> ``` -#### [](#outbound-channel-adapter)5.1.3. Outbound Channel Adapter +#### 5.1.3. Outbound Channel Adapter To send AMQP Messages to an exchange, you can configure an ``. You can optionally provide a 'routing-key' in addition to the exchange name. @@ -7068,7 +7068,7 @@ The following example shows how to define an outbound channel adapter: amqp-template="rabbitTemplate"/> ``` -#### [](#inbound-gateway)5.1.4. Inbound Gateway +#### 5.1.4. Inbound Gateway To receive an AMQP Message from a queue and respond to its reply-to address, you can configure an ``. The following example shows how to define an inbound gateway: @@ -7080,7 +7080,7 @@ The following example shows how to define an inbound gateway: connection-factory="rabbitConnectionFactory"/> ``` -#### [](#outbound-gateway)5.1.5. Outbound Gateway +#### 5.1.5. Outbound Gateway To send AMQP Messages to an exchange and receive back a response from a remote client, you can configure an ``. You can optionally provide a 'routing-key' in addition to the exchange name. @@ -7094,11 +7094,11 @@ The following example shows how to define an outbound gateway: amqp-template="rabbitTemplate"/> ``` -## [](#resources)6. Other Resources +## 6. Other Resources In addition to this reference documentation, there exist a number of other resources that may help you learn about AMQP. -### [](#further-reading)6.1. Further Reading +### 6.1. Further Reading For those who are not familiar with AMQP, the [specification](https://www.amqp.org/resources/download) is actually quite readable. It is, of course, the authoritative source of information, and the Spring AMQP code should be easy to understand for anyone who is familiar with the spec. @@ -7108,42 +7108,42 @@ We recommend reading the 0.9.1 document. There are many great articles, presentations, and blogs available on the RabbitMQ [Getting Started](https://www.rabbitmq.com/how.html) page. Since that is currently the only supported implementation for Spring AMQP, we also recommend that as a general starting point for all broker-related concerns. -## [](#change-history)Appendix A: Change History +## Appendix A: Change History This section describes what changes have been made as versions have changed. -### [](#current-release)A.1. Current Release +### A.1. Current Release See [What’s New](#whats-new). -### [](#previous-whats-new)A.2. Previous Releases +### A.2. Previous Releases -#### [](#changes-in-2-3-since-2-2)A.2.1. Changes in 2.3 Since 2.2 +#### A.2.1. Changes in 2.3 Since 2.2 This section describes the changes between version 2.2 and version 2.3. See [Change History](#change-history) for changes in previous versions. -##### [](#connection-factory-changes)Connection Factory Changes +##### Connection Factory Changes Two additional connection factories are now provided. See [Choosing a Connection Factory](#choosing-factory) for more information. -##### [](#rabbitlistener-changes-2)`@RabbitListener` Changes +##### `@RabbitListener` Changes You can now specify a reply content type. See [Reply ContentType](#reply-content-type) for more information. -##### [](#message-converter-changes)Message Converter Changes +##### Message Converter Changes The `Jackson2JMessageConverter` s can now deserialize abstract classes (including interfaces) if the `ObjectMapper` is configured with a custom deserializer. See [Deserializing Abstract Classes](#jackson-abstract) for more information. -##### [](#testing-changes)Testing Changes +##### Testing Changes A new annotation `@SpringRabbitTest` is provided to automatically configure some infrastructure beans for when you are not using `SpringBootTest`. See [@SpringRabbitTest](#spring-rabbit-test) for more information. -##### [](#rabbittemplate-changes)RabbitTemplate Changes +##### RabbitTemplate Changes The template’s `ReturnCallback` has been refactored as `ReturnsCallback` for simpler use in lambda expressions. See [Correlated Publisher Confirms and Returns](#template-confirms) for more information. @@ -7154,7 +7154,7 @@ See [Correlated Publisher Confirms and Returns](#template-confirms) for more inf When using direct reply-to, you can now configure the template such that the server does not need to return correlation data with the reply. See [RabbitMQ Direct reply-to](#direct-reply-to) for more information. -##### [](#listener-container-changes)Listener Container Changes +##### Listener Container Changes A new listener container property `consumeDelay` is now available; it is helpful when using the [RabbitMQ Sharding Plugin](https://github.com/rabbitmq/rabbitmq-sharding). @@ -7165,26 +7165,26 @@ The containers now support the `globalQos` property to apply the `prefetchCount` See [Message Listener Container Configuration](#containerAttributes) for more information. -##### [](#messagepostprocessor-changes)MessagePostProcessor Changes +##### MessagePostProcessor Changes The compressing `MessagePostProcessor` s now use a comma to separate multiple content encodings instead of a colon. The decompressors can handle both formats but, if you produce messages with this version that are consumed by versions earlier than 2.2.12, you should configure the compressor to use the old delimiter. See the IMPORTANT note in [Modifying Messages - Compression and More](#post-processing) for more information. -##### [](#multiple-broker-support-improvements)Multiple Broker Support Improvements +##### Multiple Broker Support Improvements See [Multiple Broker (or Cluster) Support](#multi-rabbit) for more information. -##### [](#republishmessagerecoverer-changes)RepublishMessageRecoverer Changes +##### RepublishMessageRecoverer Changes A new subclass of this recoverer is not provided that supports publisher confirms. See [Message Listeners and the Asynchronous Case](#async-listeners) for more information. -#### [](#changes-in-2-2-since-2-1)A.2.2. Changes in 2.2 Since 2.1 +#### A.2.2. Changes in 2.2 Since 2.1 This section describes the changes between version 2.1 and version 2.2. -##### [](#package-changes)Package Changes +##### Package Changes The following classes/interfaces have been moved from `org.springframework.amqp.rabbit.core.support` to `org.springframework.amqp.rabbit.batch`: @@ -7196,19 +7196,19 @@ The following classes/interfaces have been moved from `org.springframework.amqp. In addition, `ListenerExecutionFailedException` has been moved from `org.springframework.amqp.rabbit.listener.exception` to `org.springframework.amqp.rabbit.support`. -##### [](#dependency-changes)Dependency Changes +##### Dependency Changes JUnit (4) is now an optional dependency and will no longer appear as a transitive dependency. The `spring-rabbit-junit` module is now a **compile** dependency in the `spring-rabbit-test` module for a better target application development experience when with only a single `spring-rabbit-test` we get the full stack of testing utilities for AMQP components. -##### [](#breaking-api-changes)"Breaking" API Changes +##### "Breaking" API Changes the JUnit (5) `RabbitAvailableCondition.getBrokerRunning()` now returns a `BrokerRunningSupport` instance instead of a `BrokerRunning`, which depends on JUnit 4. It has the same API so it’s just a matter of changing the class name of any references. See [JUnit5 Conditions](#junit5-conditions) for more information. -##### [](#listenercontainer-changes)ListenerContainer Changes +##### ListenerContainer Changes Messages with fatal exceptions are now rejected and NOT requeued, by default, even if the acknowledge mode is manual. See [Exception Handling](#exception-handling) for more information. @@ -7216,7 +7216,7 @@ See [Exception Handling](#exception-handling) for more information. Listener performance can now be monitored using Micrometer `Timer` s. See [Monitoring Listener Performance](#micrometer) for more information. -##### [](#rabbitlistener-changes-3)@RabbitListener Changes +##### @RabbitListener Changes You can now configure an `executor` on each listener, overriding the factory configuration, to more easily identify threads associated with the listener. You can now override the container factory’s `acknowledgeMode` property with the annotation’s `ackMode` property. @@ -7247,7 +7247,7 @@ See [Reply Management](#async-annotation-driven-reply) for more information. You can now configure a `ReplyPostProcessor` to make modifications to a reply message before it is sent. See [Reply Management](#async-annotation-driven-reply) for more information. -##### [](#amqp-logging-appenders-changes)AMQP Logging Appenders Changes +##### AMQP Logging Appenders Changes The Log4J and Logback `AmqpAppender` s now support a `verifyHostname` SSL option. @@ -7258,12 +7258,12 @@ The appenders now support the `SaslConfig` property. See [Logging Subsystem AMQP Appenders](#logging) for more information. -##### [](#messagelisteneradapter-changes)MessageListenerAdapter Changes +##### MessageListenerAdapter Changes The `MessageListenerAdapter` provides now a new `buildListenerArguments(Object, Channel, Message)` method to build an array of arguments to be passed into target listener and an old one is deprecated. See [`MessageListenerAdapter`](#message-listener-adapter) for more information. -##### [](#exchangequeue-declaration-changes)Exchange/Queue Declaration Changes +##### Exchange/Queue Declaration Changes The `ExchangeBuilder` and `QueueBuilder` fluent APIs used to create `Exchange` and `Queue` objects for declaration by `RabbitAdmin` now support "well known" arguments. See [Builder API for Queues and Exchanges](#builder-api) for more information. @@ -7271,7 +7271,7 @@ See [Builder API for Queues and Exchanges](#builder-api) for more information. The `RabbitAdmin` has a new property `explicitDeclarationsOnly`. See [Conditional Declaration](#conditional-declaration) for more information. -##### [](#connection-factory-changes-2)Connection Factory Changes +##### Connection Factory Changes The `CachingConnectionFactory` has a new property `shuffleAddresses`. When providing a list of broker node addresses, the list will be shuffled before creating a connection so that the order in which the connections are attempted is random. @@ -7286,11 +7286,11 @@ Also, the publisher confirm type is now specified with the `ConfirmType` enum in The `RabbitConnectionFactoryBean` now uses TLS 1.2 by default when SSL is enabled. See [`RabbitConnectionFactoryBean` and Configuring SSL](#rabbitconnectionfactorybean-configuring-ssl) for more information. -##### [](#new-messagepostprocessor-classes)New MessagePostProcessor Classes +##### New MessagePostProcessor Classes Classes `DeflaterPostProcessor` and `InflaterPostProcessor` were added to support compression and decompression, respectively, when the message content-encoding is set to `deflate`. -##### [](#other-changes)Other Changes +##### Other Changes The `Declarables` object (for declaring multiple queues, exchanges, bindings) now has a filtered getter for each type. See [Declaring Collections of Exchanges, Queues, and Bindings](#collection-declaration) for more information. @@ -7307,9 +7307,9 @@ See [Message Properties Converters](#message-properties-converters) for more inf Recovery of failed producer-created batches is now supported. See [Retry with Batch Listeners](#batch-retry) for more information. -#### [](#changes-in-2-1-since-2-0)A.2.3. Changes in 2.1 Since 2.0 +#### A.2.3. Changes in 2.1 Since 2.0 -##### [](#amqp-client-library)AMQP Client library +##### AMQP Client library Spring AMQP now uses the 5.4.x version of the `amqp-client` library provided by the RabbitMQ team. This client has auto-recovery configured by default. @@ -7318,31 +7318,31 @@ See [RabbitMQ Automatic Connection/Topology recovery](#auto-recovery). | |As of version 4.0, the client enables automatic recovery by default.
While compatible with this feature, Spring AMQP has its own recovery mechanisms and the client recovery feature generally is not needed.
We recommend disabling `amqp-client` automatic recovery, to avoid getting `AutoRecoverConnectionNotCurrentlyOpenException` instances when the broker is available but the connection has not yet recovered.
Starting with version 1.7.1, Spring AMQP disables it unless you explicitly create your own RabbitMQ connection factory and provide it to the `CachingConnectionFactory`.
RabbitMQ `ConnectionFactory` instances created by the `RabbitConnectionFactoryBean` also have the option disabled by default.| |---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#package-changes-2)Package Changes +##### Package Changes Certain classes have moved to different packages. Most are internal classes and do not affect user applications. Two exceptions are `ChannelAwareMessageListener` and `RabbitListenerErrorHandler`. These interfaces are now in `org.springframework.amqp.rabbit.listener.api`. -##### [](#publisher-confirms-changes)Publisher Confirms Changes +##### Publisher Confirms Changes Channels enabled for publisher confirmations are not returned to the cache while there are outstanding confirmations. See [Correlated Publisher Confirms and Returns](#template-confirms) for more information. -##### [](#listener-container-factory-improvements)Listener Container Factory Improvements +##### Listener Container Factory Improvements You can now use the listener container factories to create any listener container, not only those for use with `@RabbitListener` annotations or the `@RabbitListenerEndpointRegistry`. See [Using Container Factories](#using-container-factories) for more information. `ChannelAwareMessageListener` now inherits from `MessageListener`. -##### [](#broker-event-listener)Broker Event Listener +##### Broker Event Listener A `BrokerEventListener` is introduced to publish selected broker events as `ApplicationEvent` instances. See [Broker Event Listener](#broker-events) for more information. -##### [](#rabbitadmin-changes-2)RabbitAdmin Changes +##### RabbitAdmin Changes The `RabbitAdmin` discovers beans of type `Declarables` (which is a container for `Declarable` - `Queue`, `Exchange`, and `Binding` objects) and declare the contained objects on the broker. Users are discouraged from using the old mechanism of declaring `>` (and others) and should use `Declarables` beans instead. @@ -7352,7 +7352,7 @@ See [Declaring Collections of Exchanges, Queues, and Bindings](#collection-decla `AnonymousQueue` instances are now declared with `x-queue-master-locator` set to `client-local` by default, to ensure the queues are created on the node the application is connected to. See [Configuring the Broker](#broker-configuration) for more information. -##### [](#rabbittemplate-changes-2)RabbitTemplate Changes +##### RabbitTemplate Changes You can now configure the `RabbitTemplate` with the `noLocalReplyConsumer` option to control a `noLocal` flag for reply consumers in the `sendAndReceive()` operations. See [Request/Reply Messaging](#request-reply) for more information. @@ -7368,32 +7368,32 @@ You can now specify an `ErrorHandler` to be invoked when using request/reply wit See `setReplyErrorHandler` on the `RabbitTemplate`. (Also since 2.0.11). -##### [](#message-conversion)Message Conversion +##### Message Conversion We introduced a new `Jackson2XmlMessageConverter` to support converting messages from and to XML format. See [`Jackson2XmlMessageConverter`](#jackson2xml) for more information. -##### [](#management-rest-api-2)Management REST API +##### Management REST API The `RabbitManagementTemplate` is now deprecated in favor of the direct `com.rabbitmq.http.client.Client` (or `com.rabbitmq.http.client.ReactorNettyClient`) usage. See [RabbitMQ REST API](#management-rest-api) for more information. -##### [](#rabbitlistener-changes-4)`@RabbitListener` Changes +##### `@RabbitListener` Changes The listener container factory can now be configured with a `RetryTemplate` and, optionally, a `RecoveryCallback` used when sending replies. See [Enable Listener Endpoint Annotations](#async-annotation-driven-enable) for more information. -##### [](#async-rabbitlistener-return)Async `@RabbitListener` Return +##### Async `@RabbitListener` Return `@RabbitListener` methods can now return `ListenableFuture` or `Mono`. See [Asynchronous `@RabbitListener` Return Types](#async-returns) for more information. -##### [](#connection-factory-bean-changes)Connection Factory Bean Changes +##### Connection Factory Bean Changes By default, the `RabbitConnectionFactoryBean` now calls `enableHostnameVerification()`. To revert to the previous behavior, set the `enableHostnameVerification` property to `false`. -##### [](#connection-factory-changes-3)Connection Factory Changes +##### Connection Factory Changes The `CachingConnectionFactory` now unconditionally disables auto-recovery in the underlying RabbitMQ `ConnectionFactory`, even if a pre-configured instance is provided in a constructor. While steps have been taken to make Spring AMQP compatible with auto recovery, certain corner cases have arisen where issues remain. @@ -7401,27 +7401,27 @@ Spring AMQP has had its own recovery mechanism since 1.0.0 and does not need to While it is still possible to enable the feature (using `cachingConnectionFactory.getRabbitConnectionFactory()` `.setAutomaticRecoveryEnabled()`) after the `CachingConnectionFactory` is constructed, **we strongly recommend that you not do so**. We recommend that you use a separate RabbitMQ `ConnectionFactory` if you need auto recovery connections when using the client factory directly (rather than using Spring AMQP components). -##### [](#listener-container-changes-2)Listener Container Changes +##### Listener Container Changes The default `ConditionalRejectingErrorHandler` now completely discards messages that cause fatal errors if an `x-death` header is present. See [Exception Handling](#exception-handling) for more information. -##### [](#immediate-requeue)Immediate requeue +##### Immediate requeue A new `ImmediateRequeueAmqpException` is introduced to notify a listener container that the message has to be re-queued. To use this feature, a new `ImmediateRequeueMessageRecoverer` implementation is added. See [Message Listeners and the Asynchronous Case](#async-listeners) for more information. -#### [](#changes-in-2-0-since-1-7)A.2.4. Changes in 2.0 Since 1.7 +#### A.2.4. Changes in 2.0 Since 1.7 -##### [](#using-cachingconnectionfactory)Using `CachingConnectionFactory` +##### Using `CachingConnectionFactory` Starting with version 2.0.2, you can configure the `RabbitTemplate` to use a different connection to that used by listener containers. This change avoids deadlocked consumers when producers are blocked for any reason. See [Using a Separate Connection](#separate-connection) for more information. -##### [](#amqp-client-library-2)AMQP Client library +##### AMQP Client library Spring AMQP now uses the new 5.0.x version of the `amqp-client` library provided by the RabbitMQ team. This client has auto recovery configured by default. @@ -7430,31 +7430,31 @@ See [RabbitMQ Automatic Connection/Topology recovery](#auto-recovery). | |As of version 4.0, the client enables automatic recovery by default.
While compatible with this feature, Spring AMQP has its own recovery mechanisms, and the client recovery feature generally is not needed.
We recommend that you disable `amqp-client` automatic recovery, to avoid getting `AutoRecoverConnectionNotCurrentlyOpenException` instances when the broker is available but the connection has not yet recovered.
Starting with version 1.7.1, Spring AMQP disables it unless you explicitly create your own RabbitMQ connection factory and provide it to the `CachingConnectionFactory`.
RabbitMQ `ConnectionFactory` instances created by the `RabbitConnectionFactoryBean` also have the option disabled by default.| |---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#general-changes)General Changes +##### General Changes The `ExchangeBuilder` now builds durable exchanges by default. The `@Exchange` annotation used within a `@QeueueBinding` also declares durable exchanges by default. The `@Queue` annotation used within a `@RabbitListener` by default declares durable queues if named and non-durable if anonymous. See [Builder API for Queues and Exchanges](#builder-api) and [Annotation-driven Listener Endpoints](#async-annotation-driven) for more information. -##### [](#deleted-classes)Deleted Classes +##### Deleted Classes `UniquelyNameQueue` is no longer provided. It is unusual to create a durable non-auto-delete queue with a unique name. This class has been deleted. If you require its functionality, use `new Queue(UUID.randomUUID().toString())`. -##### [](#new-listener-container)New Listener Container +##### New Listener Container The `DirectMessageListenerContainer` has been added alongside the existing `SimpleMessageListenerContainer`. See [Choosing a Container](#choose-container) and [Message Listener Container Configuration](#containerAttributes) for information about choosing which container to use as well as how to configure them. -##### [](#log4j-appender)Log4j Appender +##### Log4j Appender This appender is no longer available due to the end-of-life of log4j. See [Logging Subsystem AMQP Appenders](#logging) for information about the available log appenders. -##### [](#rabbittemplate-changes-3)`RabbitTemplate` Changes +##### `RabbitTemplate` Changes | |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.| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| @@ -7473,14 +7473,14 @@ See [Receiving Messages](#receiving-messages), [Request/Reply Messaging](#reques You can now use a `RabbitTemplate` to perform multiple operations on a dedicated channel. See [Scoped Operations](#scoped-operations) for more information. -##### [](#listener-adapter)Listener Adapter +##### Listener Adapter A convenient `FunctionalInterface` is available for using lambdas with the `MessageListenerAdapter`. See [`MessageListenerAdapter`](#message-listener-adapter) for more information. -##### [](#listener-container-changes-3)Listener Container Changes +##### Listener Container Changes -###### [](#prefetch-default-value)Prefetch Default Value +###### Prefetch Default Value The prefetch default value used to be 1, which could lead to under-utilization of efficient consumers. The default prefetch value is now 250, which should keep consumers busy in most common scenarios and, @@ -7491,26 +7491,26 @@ thus, improve throughput. For more background about prefetch, see this post about [consumer utilization in RabbitMQ](https://www.rabbitmq.com/blog/2014/04/14/finding-bottlenecks-with-rabbitmq-3-3/)and this post about [queuing theory](https://www.rabbitmq.com/blog/2012/05/11/some-queuing-theory-throughput-latency-and-bandwidth/). -###### [](#message-count)Message Count +###### Message Count Previously, `MessageProperties.getMessageCount()` returned `0` for messages emitted by the container. This property applies only when you use `basicGet` (for example, from `RabbitTemplate.receive()` methods) and is now initialized to `null` for container messages. -###### [](#transaction-rollback-behavior)Transaction Rollback Behavior +###### Transaction Rollback Behavior Message re-queue on transaction rollback is now consistent, regardless of whether or not a transaction manager is configured. See [A note on Rollback of Received Messages](#transaction-rollback) for more information. -###### [](#shutdown-behavior)Shutdown Behavior +###### Shutdown Behavior If the container threads do not respond to a shutdown within `shutdownTimeout`, the channels are forced closed by default. See [Message Listener Container Configuration](#containerAttributes) for more information. -###### [](#after-receive-message-post-processors)After Receive Message Post Processors +###### After Receive Message Post Processors If a `MessagePostProcessor` in the `afterReceiveMessagePostProcessors` property returns `null`, the message is discarded (and acknowledged if appropriate). -##### [](#connection-factory-changes-4)Connection Factory Changes +##### Connection Factory Changes The connection and channel listener interfaces now provide a mechanism to obtain information about exceptions. See [Connection and Channel Listeners](#connection-channel-listeners) and [Publishing is Asynchronous — How to Detect Successes and Failures](#publishing-is-async) for more information. @@ -7518,18 +7518,18 @@ See [Connection and Channel Listeners](#connection-channel-listeners) and [Publi A new `ConnectionNameStrategy` is now provided to populate the application-specific identification of the target RabbitMQ connection from the `AbstractConnectionFactory`. See [Connection and Resource Management](#connections) for more information. -##### [](#retry-changes)Retry Changes +##### Retry Changes The `MissingMessageIdAdvice` is no longer provided. Its functionality is now built-in. See [Failures in Synchronous Operations and Options for Retry](#retry) for more information. -##### [](#anonymous-queue-naming)Anonymous Queue Naming +##### Anonymous Queue Naming By default, `AnonymousQueues` are now named with the default `Base64UrlNamingStrategy` instead of a simple `UUID` string. See [`AnonymousQueue`](#anonymous-queue) for more information. -##### [](#rabbitlistener-changes-5)`@RabbitListener` Changes +##### `@RabbitListener` Changes You can now provide simple queue declarations (bound only to the default exchange) in `@RabbitListener` annotations. See [Annotation-driven Listener Endpoints](#async-annotation-driven) for more information. @@ -7552,39 +7552,39 @@ See [Annotation-driven Listener Endpoints](#async-annotation-driven) for more in Starting with version 2.0.3, one of the `@RabbitHandler` annotations on a class-level `@RabbitListener` can be designated as the default. See [Multi-method Listeners](#annotation-method-selection) for more information. -##### [](#container-conditional-rollback)Container Conditional Rollback +##### Container Conditional Rollback When using an external transaction manager (such as JDBC), rule-based rollback is now supported when you provide the container with a transaction attribute. It is also now more flexible when you use a transaction advice. See [Conditional Rollback](#conditional-rollback) for more information. -##### [](#remove-jackson-1-x-support)Remove Jackson 1.x support +##### Remove Jackson 1.x support Deprecated in previous versions, Jackson `1.x` converters and related components have now been deleted. You can use similar components based on Jackson 2.x. See [Jackson2JsonMessageConverter](#json-message-converter) for more information. -##### [](#json-message-converter-2)JSON Message Converter +##### JSON Message Converter When the `*TypeId*` is set to `Hashtable` for an inbound JSON message, the default conversion type is now `LinkedHashMap`. Previously, it was `Hashtable`. To revert to a `Hashtable`, you can use `setDefaultMapType` on the `DefaultClassMapper`. -##### [](#xml-parsers)XML Parsers +##### XML Parsers When parsing `Queue` and `Exchange` XML components, the parsers no longer register the `name` attribute value as a bean alias if an `id` attribute is present. See [A Note On the `id` and `name` Attributes](#note-id-name) for more information. -##### [](#blocked-connection)Blocked Connection +##### Blocked Connection You can now inject the `com.rabbitmq.client.BlockedListener` into the `org.springframework.amqp.rabbit.connection.Connection` object. Also, the `ConnectionBlockedEvent` and `ConnectionUnblockedEvent` events are emitted by the `ConnectionFactory` when the connection is blocked or unblocked by the Broker. See [Connection and Resource Management](#connections) for more information. -#### [](#changes-in-1-7-since-1-6)A.2.5. Changes in 1.7 Since 1.6 +#### A.2.5. Changes in 1.7 Since 1.6 -##### [](#amqp-client-library-3)AMQP Client library +##### AMQP Client library Spring AMQP now uses the new 4.0.x version of the `amqp-client` library provided by the RabbitMQ team. This client has auto-recovery configured by default. @@ -7593,75 +7593,75 @@ See [RabbitMQ Automatic Connection/Topology recovery](#auto-recovery). | |The 4.0.x client enables automatic recovery by default.
While compatible with this feature, Spring AMQP has its own recovery mechanisms, and the client recovery feature generally is not needed.
We recommend disabling `amqp-client` automatic recovery, to avoid getting `AutoRecoverConnectionNotCurrentlyOpenException` instances when the broker is available but the connection has not yet recovered.
Starting with version 1.7.1, Spring AMQP disables it unless you explicitly create your own RabbitMQ connection factory and provide it to the `CachingConnectionFactory`.
RabbitMQ `ConnectionFactory` instances created by the `RabbitConnectionFactoryBean` also have the option disabled by default.| |---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#log4j-2-upgrade)Log4j 2 upgrade +##### Log4j 2 upgrade The minimum Log4j 2 version (for the `AmqpAppender`) is now `2.7`. The framework is no longer compatible with previous versions. See [Logging Subsystem AMQP Appenders](#logging) for more information. -##### [](#logback-appender-2)Logback Appender +##### Logback Appender This appender no longer captures caller data (method, line number) by default. You can re-enable it by setting the `includeCallerData` configuration option. See [Logging Subsystem AMQP Appenders](#logging) for information about the available log appenders. -##### [](#spring-retry-upgrade)Spring Retry Upgrade +##### Spring Retry Upgrade The minimum Spring Retry version is now `1.2`. The framework is no longer compatible with previous versions. -###### [](#shutdown-behavior-2)Shutdown Behavior +###### Shutdown Behavior You can now set `forceCloseChannel` to `true` so that, if the container threads do not respond to a shutdown within `shutdownTimeout`, the channels are forced closed, causing any unacked messages to be re-queued. See [Message Listener Container Configuration](#containerAttributes) for more information. -##### [](#fasterxml-jackson-upgrade)FasterXML Jackson upgrade +##### FasterXML Jackson upgrade The minimum Jackson version is now `2.8`. The framework is no longer compatible with previous versions. -##### [](#junit-rules-2)JUnit `@Rules` +##### JUnit `@Rules` Rules that have previously been used internally by the framework have now been made available in a separate jar called `spring-rabbit-junit`. See [JUnit4 `@Rules`](#junit-rules) for more information. -##### [](#container-conditional-rollback-2)Container Conditional Rollback +##### Container Conditional Rollback When you use an external transaction manager (such as JDBC), rule-based rollback is now supported when you provide the container with a transaction attribute. It is also now more flexible when you use a transaction advice. -##### [](#connection-naming-strategy)Connection Naming Strategy +##### Connection Naming Strategy A new `ConnectionNameStrategy` is now provided to populate the application-specific identification of the target RabbitMQ connection from the `AbstractConnectionFactory`. See [Connection and Resource Management](#connections) for more information. -##### [](#listener-container-changes-4)Listener Container Changes +##### Listener Container Changes -###### [](#transaction-rollback-behavior-2)Transaction Rollback Behavior +###### Transaction Rollback Behavior You can now configure message re-queue on transaction rollback to be consistent, regardless of whether or not a transaction manager is configured. See [A note on Rollback of Received Messages](#transaction-rollback) for more information. -#### [](#earlier-releases)A.2.6. Earlier Releases +#### A.2.6. Earlier Releases See [Previous Releases](#previous-whats-new) for changes in previous versions. -#### [](#changes-in-1-6-since-1-5)A.2.7. Changes in 1.6 Since 1.5 +#### A.2.7. Changes in 1.6 Since 1.5 -##### [](#testing-support)Testing Support +##### Testing Support A new testing support library is now provided. See [Testing Support](#testing) for more information. -##### [](#builder)Builder +##### Builder Builders that provide a fluent API for configuring `Queue` and `Exchange` objects are now available. See [Builder API for Queues and Exchanges](#builder-api) for more information. -##### [](#namespace-changes)Namespace Changes +##### Namespace Changes -###### [](#connection-factory-2)Connection Factory +###### Connection Factory You can now add a `thread-factory` to a connection factory bean declaration — for example, to name the threads created by the `amqp-client` library. @@ -7670,19 +7670,19 @@ See [Connection and Resource Management](#connections) for more information. When you use `CacheMode.CONNECTION`, you can now limit the total number of connections allowed. See [Connection and Resource Management](#connections) for more information. -###### [](#queue-definitions)Queue Definitions +###### Queue Definitions You can now provide a naming strategy for anonymous queues. See [`AnonymousQueue`](#anonymous-queue) for more information. -##### [](#listener-container-changes-5)Listener Container Changes +##### Listener Container Changes -###### [](#idle-message-listener-detection)Idle Message Listener Detection +###### Idle Message Listener Detection You can now configure listener containers to publish `ApplicationEvent` instances when idle. See [Detecting Idle Asynchronous Consumers](#idle-containers) for more information. -###### [](#mismatched-queue-detection)Mismatched Queue Detection +###### Mismatched Queue Detection By default, when a listener container starts, if queues with mismatched properties or arguments are detected, the container logs the exception but continues to listen. @@ -7691,34 +7691,34 @@ starting if the problem is detected during startup. It also stops the container if the problem is detected later, such as after recovering from a connection failure. See [Message Listener Container Configuration](#containerAttributes) for more information. -###### [](#listener-container-logging)Listener Container Logging +###### Listener Container Logging Now, listener container provides its `beanName` to the internal `SimpleAsyncTaskExecutor` as a `threadNamePrefix`. It is useful for logs analysis. -###### [](#default-error-handler)Default Error Handler +###### Default Error Handler The default error handler (`ConditionalRejectingErrorHandler`) now considers irrecoverable `@RabbitListener`exceptions as fatal. See [Exception Handling](#exception-handling) for more information. -##### [](#autodeclare-and-rabbitadmin-instances)`AutoDeclare` and `RabbitAdmin` Instances +##### `AutoDeclare` and `RabbitAdmin` Instances See [Message Listener Container Configuration](#containerAttributes) (`autoDeclare`) for some changes to the semantics of that option with respect to the use of `RabbitAdmin` instances in the application context. -##### [](#amqptemplate-receive-with-timeout)`AmqpTemplate`: Receive with Timeout +##### `AmqpTemplate`: Receive with Timeout A number of new `receive()` methods with `timeout` have been introduced for the `AmqpTemplate`and its `RabbitTemplate` implementation. See [Polling Consumer](#polling-consumer) for more information. -##### [](#using-asyncrabbittemplate)Using `AsyncRabbitTemplate` +##### Using `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 [Async Rabbit Template](#async-template) for more information. -##### [](#rabbittemplate-changes-4)`RabbitTemplate` Changes +##### `RabbitTemplate` Changes 1.4.1 introduced the ability to use [direct reply-to](https://www.rabbitmq.com/direct-reply-to.html) when the broker supports it. It is more efficient than using a temporary queue for each reply. @@ -7728,14 +7728,14 @@ See [RabbitMQ Direct reply-to](#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](https://www.rabbitmq.com/validated-user-id.html) and [Validated User Id](#template-user-id) for more information. -##### [](#message-properties)Message Properties +##### Message Properties -###### [](#using-correlationid)Using `CorrelationId` +###### Using `CorrelationId` The `correlationId` message property can now be a `String`. See [Message Properties Converters](#message-properties-converters) for more information. -###### [](#long-string-headers)Long String Headers +###### Long String Headers Previously, the `DefaultMessagePropertiesConverter` “converted” headers longer than the long string limit (default 1024) to a `DataInputStream` (actually, it referenced the `LongString` instance’s `DataInputStream`). @@ -7747,7 +7747,7 @@ A large incoming `LongString` is now correctly “converted” on output too. See [Message Properties Converters](#message-properties-converters) for more information. -###### [](#inbound-delivery-mode)Inbound Delivery Mode +###### Inbound Delivery Mode The `deliveryMode` property is no longer mapped to the `MessageProperties.deliveryMode`. This change avoids unintended propagation if the the same `MessageProperties` object is used to send an outbound message. @@ -7759,7 +7759,7 @@ When using annotated endpoints, the header is provided in the header named `Amqp See [Annotated Endpoint Method Signature](#async-annotation-driven-enable-signature) for more information. -###### [](#inbound-user-id)Inbound User ID +###### Inbound User ID The `user_id` property is no longer mapped to the `MessageProperties.userId`. This change avoids unintended propagation if the the same `MessageProperties` object is used to send an outbound message. @@ -7771,9 +7771,9 @@ When you use annotated endpoints, the header is provided in the header named `Am See [Annotated Endpoint Method Signature](#async-annotation-driven-enable-signature) for more information. -##### [](#rabbitadmin-changes-3)`RabbitAdmin` Changes +##### `RabbitAdmin` Changes -###### [](#declaration-failures)Declaration Failures +###### Declaration Failures Previously, the `ignoreDeclarationFailures` flag took effect only for `IOException` on the channel (such as mis-matched arguments). @@ -7782,9 +7782,9 @@ In addition, a `DeclarationExceptionEvent` is now published whenever a declarati The `RabbitAdmin` last declaration event is also available as a property `lastDeclarationExceptionEvent`. See [Configuring the Broker](#broker-configuration) for more information. -##### [](#rabbitlistener-changes-6)`@RabbitListener` Changes +##### `@RabbitListener` Changes -###### [](#multiple-containers-for-each-bean)Multiple Containers for Each Bean +###### Multiple Containers for Each Bean When you use Java 8 or later, you can now add multiple `@RabbitListener` annotations to `@Bean` classes or their methods. @@ -7792,43 +7792,43 @@ When using Java 7 or earlier, you can use the `@RabbitListeners` container annot functionality. See [`@Repeatable` `@RabbitListener`](#repeatable-rabbit-listener) for more information. -###### [](#sendto-spel-expressions)`@SendTo` SpEL Expressions +###### `@SendTo` SpEL Expressions `@SendTo` for routing replies with no `replyTo` property can now be SpEL expressions evaluated against the request/reply. See [Reply Management](#async-annotation-driven-reply) for more information. -###### [](#queuebinding-improvements)`@QueueBinding` Improvements +###### `@QueueBinding` Improvements You can now specify arguments for queues, exchanges, and bindings in `@QueueBinding` annotations. Header exchanges are now supported by `@QueueBinding`. See [Annotation-driven Listener Endpoints](#async-annotation-driven) for more information. -##### [](#delayed-message-exchange-2)Delayed Message Exchange +##### Delayed Message Exchange Spring AMQP now has first class support for the RabbitMQ Delayed Message Exchange plugin. See [Delayed Message Exchange](#delayed-message-exchange) for more information. -##### [](#exchange-internal-flag)Exchange Internal Flag +##### Exchange Internal Flag Any `Exchange` definitions can now be marked as `internal`, and `RabbitAdmin` passes the value to the broker when declaring the exchange. See [Configuring the Broker](#broker-configuration) for more information. -##### [](#cachingconnectionfactory-changes)`CachingConnectionFactory` Changes +##### `CachingConnectionFactory` Changes -###### [](#cachingconnectionfactory-cache-statistics)`CachingConnectionFactory` Cache Statistics +###### `CachingConnectionFactory` Cache Statistics The `CachingConnectionFactory` now provides cache properties at runtime and over JMX. See [Runtime Cache Properties](#runtime-cache-properties) for more information. -###### [](#accessing-the-underlying-rabbitmq-connection-factory)Accessing the Underlying RabbitMQ Connection Factory +###### Accessing the Underlying RabbitMQ Connection Factory A new getter has been added to provide access to the underlying factory. You can use this getter, for example, to add custom connection properties. See [Adding Custom Client Connection Properties](#custom-client-props) for more information. -###### [](#channel-cache)Channel Cache +###### Channel Cache The default channel cache size has been increased from 1 to 25. See [Connection and Resource Management](#connections) for more information. @@ -7836,63 +7836,63 @@ See [Connection and Resource Management](#connections) 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. -##### [](#using-rabbitconnectionfactorybean)Using `RabbitConnectionFactoryBean` +##### Using `RabbitConnectionFactoryBean` The factory bean now exposes a property to add client connection properties to connections made by the resulting factory. -##### [](#java-deserialization-2)Java Deserialization +##### Java Deserialization You can now configure a “allowed list” of allowable classes when you use Java deserialization. You should consider creating an allowed list if you accept messages with serialized java objects from untrusted sources. See [Java Deserialization](#java-deserialization) for more information. -##### [](#json-messageconverter)JSON `MessageConverter` +##### JSON `MessageConverter` Improvements to the JSON message converter now allow the consumption of messages that do not have type information in message headers. See [Message Conversion for Annotated Methods](#async-annotation-conversion) and [Jackson2JsonMessageConverter](#json-message-converter) for more information. -##### [](#logging-appenders)Logging Appenders +##### Logging Appenders -###### [](#log4j-2)Log4j 2 +###### Log4j 2 A log4j 2 appender has been added, and the appenders can now be configured with an `addresses` property to connect to a broker cluster. -###### [](#client-connection-properties)Client Connection Properties +###### Client Connection Properties You can now add custom client connection properties to RabbitMQ connections. See [Logging Subsystem AMQP Appenders](#logging) for more information. -#### [](#changes-in-1-5-since-1-4)A.2.8. Changes in 1.5 Since 1.4 +#### A.2.8. Changes in 1.5 Since 1.4 -##### [](#spring-erlang-is-no-longer-supported)`spring-erlang` Is No Longer Supported +##### `spring-erlang` Is No Longer Supported The `spring-erlang` jar is no longer included in the distribution. Use [the RabbitMQ REST API](#management-rest-api) instead. -##### [](#cachingconnectionfactory-changes-2)`CachingConnectionFactory` Changes +##### `CachingConnectionFactory` Changes -###### [](#empty-addresses-property-in-cachingconnectionfactory)Empty Addresses Property in `CachingConnectionFactory` +###### Empty Addresses Property in `CachingConnectionFactory` Previously, if the connection factory was configured with a host and 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 and port are used. -###### [](#uri-constructor)URI Constructor +###### URI Constructor The `CachingConnectionFactory` has an additional constructor, with a `URI` parameter, to configure the broker connection. -###### [](#connection-reset)Connection Reset +###### Connection Reset A new method called `resetConnection()` has been added to let users reset the connection (or connections). You might use this, for example, to reconnect to the primary broker after failing over to the secondary broker. This **does** 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)Properties to Control Container Queue Declaration Behavior +##### 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. @@ -7905,11 +7905,11 @@ retried the missing queues on a fixed interval of 60 seconds. The `declarationRetries`, `failedDeclarationRetryInterval`, and `retryDeclarationInterval` properties are now configurable. See [Message Listener Container Configuration](#containerAttributes) for more information. -##### [](#class-package-change)Class Package Change +##### Class Package Change The `RabbitGatewaySupport` class has been moved from `o.s.amqp.rabbit.core.support` to `o.s.amqp.rabbit.core`. -##### [](#defaultmessagepropertiesconverter-changes)`DefaultMessagePropertiesConverter` Changes +##### `DefaultMessagePropertiesConverter` Changes You can now configure the `DefaultMessagePropertiesConverter` to determine the maximum length of a `LongString` that is converted @@ -7918,60 +7918,60 @@ 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)`@RabbitListener` Improvements +##### `@RabbitListener` Improvements -###### [](#queuebinding-for-rabbitlistener)`@QueueBinding` for `@RabbitListener` +###### `@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)SpEL in `@SendTo` +###### SpEL in `@SendTo` The default reply address (`@SendTo`) for a `@RabbitListener` can now be a SpEL expression. -###### [](#multiple-queue-names-through-properties)Multiple Queue Names through Properties +###### Multiple Queue Names through Properties You can now use a combination of SpEL and property placeholders to specify multiple queues for a listener. See [Annotation-driven Listener Endpoints](#async-annotation-driven) for more information. -##### [](#automatic-exchange-queue-and-binding-declaration)Automatic Exchange, Queue, and Binding Declaration +##### Automatic Exchange, Queue, and Binding Declaration You can now declare beans that define a collection of these entities, and the `RabbitAdmin` adds the contents to the list of entities that it declares when a connection is established. See [Declaring Collections of Exchanges, Queues, and Bindings](#collection-declaration) for more information. -##### [](#rabbittemplate-changes-5)`RabbitTemplate` Changes +##### `RabbitTemplate` Changes -###### [](#reply-address-added)`reply-address` Added +###### `reply-address` Added The `reply-address` attribute has been added to the `` component as an alternative `reply-queue`. See [Request/Reply Messaging](#request-reply) for more information. (Also available in 1.4.4 as a setter on the `RabbitTemplate`). -###### [](#blocking-receive-methods)Blocking `receive` Methods +###### Blocking `receive` Methods The `RabbitTemplate` now supports blocking in `receive` and `convertAndReceive` methods. See [Polling Consumer](#polling-consumer) for more information. -###### [](#mandatory-with-sendandreceive-methods)Mandatory with `sendAndReceive` Methods +###### Mandatory with `sendAndReceive` Methods When the `mandatory` flag is set when using the `sendAndReceive` and `convertSendAndReceive` methods, the calling thread throws an `AmqpMessageReturnedException` if the request message cannot be deliverted. See [Reply Timeout](#reply-timeout) for more information. -###### [](#improper-reply-listener-configuration)Improper Reply Listener Configuration +###### Improper Reply Listener Configuration The framework tries to verify proper configuration of a reply listener container when using a named reply queue. See [Reply Listener Container](#reply-listener) for more information. -##### [](#rabbitmanagementtemplate-added)`RabbitManagementTemplate` Added +##### `RabbitManagementTemplate` Added The `RabbitManagementTemplate` has been introduced to monitor and configure the RabbitMQ Broker by using the REST API provided by its [management plugin](https://www.rabbitmq.com/management.html). See [RabbitMQ REST API](#management-rest-api) for more information. -##### [](#listener-container-bean-names-xml)Listener Container Bean Names (XML) +##### | |The `id` attribute on the `` element has been removed.
Starting with this release, the `id` on the `` 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 `` is parsed with the same `id` as an existing bean, the new definition overrides the existing one.
Previously, bean names were composed from the `id` attributes of the `` and `` elements.

When migrating to this release, if you have `id` attributes on your `` elements, remove them and set the `id` on the child `` element instead.| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| @@ -7980,89 +7980,89 @@ However, to support starting and stopping containers as a group, a new `group` a When this attribute is defined, the containers created by this element are added to a bean with this name, of type `Collection`. You can iterate over this group to start and stop containers. -##### [](#class-level-rabbitlistener)Class-Level `@RabbitListener` +##### Class-Level `@RabbitListener` The `@RabbitListener` annotation can now be applied at the class level. Together with the new `@RabbitHandler` method annotation, this lets you select the handler method based on payload type. See [Multi-method Listeners](#annotation-method-selection) for more information. -##### [](#simplemessagelistenercontainer-backoff-support)`SimpleMessageListenerContainer`: BackOff Support +##### `SimpleMessageListenerContainer`: BackOff Support The `SimpleMessageListenerContainer` can now be supplied with a `BackOff` instance for `consumer` startup recovery. See [Message Listener Container Configuration](#containerAttributes) for more information. -##### [](#channel-close-logging-2)Channel Close Logging +##### Channel Close Logging A mechanism to control the log levels of channel closure has been introduced. See [Logging Channel Close Events](#channel-close-logging). -##### [](#application-events)Application Events +##### Application Events The `SimpleMessageListenerContainer` now emits application events when consumers fail. See [Consumer Events](#consumer-events) for more information. -##### [](#consumer-tag-configuration)Consumer Tag Configuration +##### 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 [Consumer Tags](#consumerTags). -##### [](#using-messagelisteneradapter)Using `MessageListenerAdapter` +##### Using `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 from which the message was received. -##### [](#localizedqueueconnectionfactory-added)`LocalizedQueueConnectionFactory` Added +##### `LocalizedQueueConnectionFactory` Added `LocalizedQueueConnectionFactory` is a new connection factory that connects to the node in a cluster where a mirrored queue actually resides. See [Queue Affinity and the `LocalizedQueueConnectionFactory`](#queue-affinity). -##### [](#anonymous-queue-naming-2)Anonymous Queue Naming +##### Anonymous Queue Naming Starting with version 1.5.3, you can now control how `AnonymousQueue` names are generated. See [`AnonymousQueue`](#anonymous-queue) for more information. -#### [](#changes-in-1-4-since-1-3)A.2.9. Changes in 1.4 Since 1.3 +#### A.2.9. Changes in 1.4 Since 1.3 -##### [](#rabbitlistener-annotation)`@RabbitListener` Annotation +##### `@RabbitListener` Annotation POJO listeners can be annotated with `@RabbitListener`, enabled by `@EnableRabbit` or ``. Spring Framework 4.1 is required for this feature. See [Annotation-driven Listener Endpoints](#async-annotation-driven) for more information. -##### [](#rabbitmessagingtemplate-added)`RabbitMessagingTemplate` Added +##### `RabbitMessagingTemplate` Added A new `RabbitMessagingTemplate` lets you interact with RabbitMQ by using `spring-messaging` `Message` instances. Internally, it uses the `RabbitTemplate`, which you can configure as normal. Spring Framework 4.1 is required for this feature. See [Messaging Integration](#template-messaging) for more information. -##### [](#listener-container-missingqueuesfatal-attribute)Listener Container `missingQueuesFatal` Attribute +##### Listener Container `missingQueuesFatal` Attribute 1.3.5 introduced the `missingQueuesFatal` property on the `SimpleMessageListenerContainer`. This is now available on the listener container namespace element. See [Message Listener Container Configuration](#containerAttributes). -##### [](#rabbittemplate-confirmcallback-interface)RabbitTemplate `ConfirmCallback` Interface +##### RabbitTemplate `ConfirmCallback` Interface The `confirm` method on this interface has an additional parameter called `cause`. When available, this parameter contains the reason for a negative acknowledgement (nack). See [Correlated Publisher Confirms and Returns](#template-confirms). -##### [](#rabbitconnectionfactorybean-added)`RabbitConnectionFactoryBean` Added +##### `RabbitConnectionFactoryBean` Added `RabbitConnectionFactoryBean` creates the underlying RabbitMQ `ConnectionFactory` used by the `CachingConnectionFactory`. This enables configuration of SSL options using Spring’s dependency injection. See [Configuring the Underlying Client Connection Factory](#connection-factory). -##### [](#using-cachingconnectionfactory-2)Using `CachingConnectionFactory` +##### Using `CachingConnectionFactory` The `CachingConnectionFactory` now lets the `connectionTimeout` be set as a property or as an attribute in the namespace. It sets the property on the underlying RabbitMQ `ConnectionFactory`. See [Configuring the Underlying Client Connection Factory](#connection-factory). -##### [](#log-appender)Log Appender +##### Log Appender The Logback `org.springframework.amqp.rabbit.logback.AmqpAppender` has been introduced. It provides options similar to `org.springframework.amqp.rabbit.log4j.AmqpAppender`. @@ -8074,13 +8074,13 @@ 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-2)Listener Queues +##### Listener Queues The listener container now, by default, redeclares any missing queues during startup. A new `auto-declare` attribute has been added to the `` to prevent these re-declarations. See [`auto-delete` Queues](#lc-auto-delete). -##### [](#rabbittemplate-mandatory-and-connectionfactoryselector-expressions)`RabbitTemplate`: `mandatory` and `connectionFactorySelector` Expressions +##### `RabbitTemplate`: `mandatory` and `connectionFactorySelector` Expressions The `mandatoryExpression`, `sendConnectionFactorySelectorExpression`, and `receiveConnectionFactorySelectorExpression` SpEL Expression`s properties have been added to `RabbitTemplate`. The `mandatoryExpression` is used to evaluate a `mandatory` boolean value against each request message when a `ReturnCallback` is in use. @@ -8088,17 +8088,17 @@ See [Correlated Publisher Confirms and Returns](#template-confirms). 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 [Routing Connection Factory](#routing-connection-factory). -##### [](#listeners-and-the-routing-connection-factory)Listeners and the Routing Connection Factory +##### Listeners and the Routing Connection Factory You can configure a `SimpleMessageListenerContainer` with a routing connection factory to enable connection selection based on the queue names. See [Routing Connection Factory](#routing-connection-factory). -##### [](#rabbittemplate-recoverycallback-option)`RabbitTemplate`: `RecoveryCallback` Option +##### `RabbitTemplate`: `RecoveryCallback` Option The `recoveryCallback` property has been added for use in the `retryTemplate.execute()`. See [Adding Retry Capabilities](#template-retry). -##### [](#messageconversionexception-change)`MessageConversionException` Change +##### `MessageConversionException` Change This exception is now a subclass of `AmqpException`. Consider the following code: @@ -8117,24 +8117,24 @@ catch (MessageConversionException e) { The second catch block is no longer reachable and needs to be moved above the catch-all `AmqpException` catch block. -##### [](#rabbitmq-3-4-compatibility)RabbitMQ 3.4 Compatibility +##### RabbitMQ 3.4 Compatibility Spring AMQP is now compatible with the RabbitMQ 3.4, including direct reply-to. See [Compatibility](#compatibility) and [RabbitMQ Direct reply-to](#direct-reply-to) for more information. -##### [](#contenttypedelegatingmessageconverter-added)`ContentTypeDelegatingMessageConverter` Added +##### `ContentTypeDelegatingMessageConverter` Added The `ContentTypeDelegatingMessageConverter` has been introduced to select the `MessageConverter` to use, based on the `contentType` property in the `MessageProperties`. See [Message Converters](#message-converters) for more information. -#### [](#changes-in-1-3-since-1-2)A.2.10. Changes in 1.3 Since 1.2 +#### A.2.10. Changes in 1.3 Since 1.2 -##### [](#listener-concurrency-2)Listener Concurrency +##### Listener Concurrency The listener container now supports dynamic scaling of the number of consumers based on workload, or you can programmatically change the concurrency without stopping the container. See [Listener Concurrency](#listener-concurrency). -##### [](#listener-queues-3)Listener Queues +##### Listener Queues The listener container now permits the queues on which it listens to be modified at runtime. Also, the container now starts if at least one of its configured queues is available for use. @@ -8143,28 +8143,28 @@ See [Listener Container Queues](#listener-queues) This listener container now redeclares any auto-delete queues during startup. See [`auto-delete` Queues](#lc-auto-delete). -##### [](#consumer-priority-2)Consumer Priority +##### Consumer Priority The listener container now supports consumer arguments, letting the `x-priority` argument be set. See [Consumer Priority](#consumer-priority). -##### [](#exclusive-consumer-2)Exclusive Consumer +##### Exclusive Consumer You can now configure `SimpleMessageListenerContainer` with a single `exclusive` consumer, preventing other consumers from listening to the queue. See [Exclusive Consumer](#exclusive-consumer). -##### [](#rabbit-admin)Rabbit Admin +##### Rabbit Admin You can now have the broker generate the queue name, regardless of `durable`, `autoDelete`, and `exclusive` settings. See [Configuring the Broker](#broker-configuration). -##### [](#direct-exchange-binding)Direct Exchange Binding +##### 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`. If you wish to bind with an empty string routing key, you need to specify `key=""`. -##### [](#amqptemplate-changes)`AmqpTemplate` Changes +##### `AmqpTemplate` Changes The `AmqpTemplate` now provides several synchronous `receiveAndReply` methods. These are implemented by the `RabbitTemplate`. @@ -8173,59 +8173,59 @@ For more information see [Receiving Messages](#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 [Adding Retry Capabilities](#template-retry). -##### [](#caching-connection-factory)Caching Connection Factory +##### Caching Connection Factory You can now configure the caching connection factory to cache `Connection` instances and their `Channel` instances instead of using a single connection and caching only `Channel` instances. See [Connection and Resource Management](#connections). -##### [](#binding-arguments)Binding Arguments +##### Binding Arguments The `` of the `` now supports parsing of the `` sub-element. You can now configure the `` of the `` with a `key/value` attribute pair (to match on a single header) or with a `` sub-element (allowing matching on multiple headers). These options are mutually exclusive. See [Headers Exchange](#headers-exchange). -##### [](#routing-connection-factory-2)Routing Connection Factory +##### Routing Connection Factory A new `SimpleRoutingConnectionFactory` has been introduced. It allows configuration of `ConnectionFactories` mapping, to determine the target `ConnectionFactory` to use at runtime. See [Routing Connection Factory](#routing-connection-factory). -##### [](#messagebuilder-and-messagepropertiesbuilder)`MessageBuilder` and `MessagePropertiesBuilder` +##### `MessageBuilder` and `MessagePropertiesBuilder` “Fluent APIs” for building messages or message properties are now provided. See [Message Builder API](#message-builder). -##### [](#retryinterceptorbuilder-change)`RetryInterceptorBuilder` Change +##### `RetryInterceptorBuilder` Change A “Fluent API” for building listener container retry interceptors is now provided. See [Failures in Synchronous Operations and Options for Retry](#retry). -##### [](#republishmessagerecoverer-added)`RepublishMessageRecoverer` Added +##### `RepublishMessageRecoverer` Added 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 [Message Listeners and the Asynchronous Case](#async-listeners). -##### [](#default-error-handler-since-1-3-2)Default Error Handler (Since 1.3.2) +##### A default `ConditionalRejectingErrorHandler` has been added to the listener container. This error handler detects fatal message conversion problems and instructs the container to reject the message to prevent the broker from continually redelivering the unconvertible message. See [Exception Handling](#exception-handling). -##### [](#listener-container-missingqueuesfatal-property-since-1-3-5)Listener Container 'missingQueuesFatal` Property (Since 1.3.5) +##### The `SimpleMessageListenerContainer` now has a property called `missingQueuesFatal` (default: `true`). Previously, missing queues were always fatal. See [Message Listener Container Configuration](#containerAttributes). -#### [](#changes-to-1-2-since-1-1)A.2.11. Changes to 1.2 Since 1.1 +#### A.2.11. Changes to 1.2 Since 1.1 -##### [](#rabbitmq-version)RabbitMQ Version +##### RabbitMQ Version Spring AMQP now uses 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-2)Rabbit Admin +##### Rabbit Admin `RabbitAdmin` now provides an option to let exchange, queue, and binding declarations continue when a declaration fails. Previously, all declarations stopped on a failure. @@ -8236,7 +8236,7 @@ An example where this might be useful is when a queue declaration fails because You can use this determine if a queue exists on the broker (returns `null` for a non-existent queue). In addition, it returns the current number of messages in the queue as well as the current number of consumers. -##### [](#rabbit-template)Rabbit Template +##### Rabbit Template Previously, when the `…​sendAndReceive()` methods were used with a fixed reply queue, two custom headers were used for correlation data and to retain and restore reply queue information. With this release, the standard message property (`correlationId`) is used by default, although you can specify a custom property to use instead. @@ -8245,11 +8245,11 @@ In addition, nested `replyTo` information is now retained internally in the temp The `immediate` property is deprecated. You must not set this property when using RabbitMQ 3.0.x or greater. -##### [](#json-message-converters)JSON Message Converters +##### 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-and-other-items)Automatic Declaration of Queues and Other Items +##### Automatic Declaration of Queues and Other Items Previously, when declaring queues, exchanges and bindings, you could not define which connection factory was used for the declarations. Each `RabbitAdmin` declared all components by using its connection. @@ -8257,20 +8257,20 @@ Each `RabbitAdmin` declared all components by using its connection. Starting with this release, you can now limit declarations to specific `RabbitAdmin` instances. See [Conditional Declaration](#conditional-declaration). -##### [](#amqp-remoting)AMQP Remoting +##### AMQP Remoting Facilities are now provided for using Spring remoting techniques, using AMQP as the transport for the RPC calls. For more information see [Spring Remoting with AMQP](#remoting) -##### [](#requested-heart-beats)Requested Heart Beats +##### 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`. -#### [](#changes-to-1-1-since-1-0)A.2.12. Changes to 1.1 Since 1.0 +#### A.2.12. Changes to 1.1 Since 1.0 -##### [](#general)General +##### General Spring-AMQP is now built with Gradle. @@ -8280,7 +8280,7 @@ Adds support for HA queues and broker failover. Adds support for dead letter exchanges and dead letter queues. -##### [](#amqp-log4j-appender)AMQP Log4j Appender +##### AMQP Log4j Appender Adds an option to support adding a message ID to logged messages. diff --git a/docs/spring-amqp/spring-amqp.md b/docs/spring-amqp/spring-amqp.md index 249821ea7dc2d395941b5a7f612492583d60a8e6..304d604c040e3e86a391be376462d4c9bfa97e3e 100644 --- a/docs/spring-amqp/spring-amqp.md +++ b/docs/spring-amqp/spring-amqp.md @@ -1,34 +1,34 @@ # Spring AMQP -## [](#preface)1。前言 +## 1.前言 Spring AMQP 项目将核心 Spring 概念应用于基于 AMQP 的消息传递解决方案的开发。我们提供了一个“模板”,作为发送和接收消息的高级抽象。我们还为消息驱动的 POJO 提供支持。这些库促进了 AMQP 资源的管理,同时促进了依赖注入和声明式配置的使用。在所有这些情况下,你都可以看到与 Spring 框架中的 JMS 支持的相似之处。有关其他项目相关信息,请访问 Spring AMQP 项目[homepage](https://projects.spring.io/spring-amqp/)。 -## [](#whats-new)2。最新更新 +## 2.最新更新 -### [](#changes-in-2-4-since-2-3)2.1。2.4 自 2.3 以来的变化 +### 2.1. 2.4 自 2.3 以来的变化 本部分描述了版本 2.4 和版本 2.4 之间的更改。有关以前版本的更改,请参见[变更历史](#change-history)。 -#### [](#rabbitlistener-changes)2.1.1。`@RabbitListener`变化 +#### 2.1.1.`@RabbitListener`变化 `MessageProperties`现在可用于参数匹配。有关更多信息,请参见[带注释的端点方法签名](#async-annotation-driven-enable-signature)。 -#### [](#rabbitadmin-changes)2.1.2。`RabbitAdmin`变化 +#### 2.1.2.`RabbitAdmin`变化 一个新的属性`recoverManualDeclarations`允许恢复手动声明的队列/交换/绑定。有关更多信息,请参见[恢复自动删除声明](#declarable-recovery)。 -#### [](#remoting-support)2.1.3。远程支持 +#### 2.1.3.远程支持 使用 Spring Framework 的 RMI 支持的远程支持已被弃用,并将在 3.0 中删除。有关更多信息,请参见[Spring Remoting with AMQP](#remoting)。 -## [](#introduction)3。导言 +## 3.导言 参考文档的第一部分是对 Spring AMQP 和底层概念的高级概述。它包括一些代码片段,可以让你尽快启动和运行。 -### [](#quick-tour)3.1。不耐烦人士的快速之旅 +### 3.1.不耐烦人士的快速之旅 -#### [](#introduction-2)3.1.1。导言 +#### 3.1.1.导言 这是从 AMQP 开始的五分钟之旅。 @@ -48,13 +48,13 @@ Spring AMQP 项目将核心 Spring 概念应用于基于 AMQP 的消息传递解 compile 'org.springframework.amqp:spring-rabbit:2.4.2' ``` -##### [](#compatibility)兼容性 +##### 兼容性 -Spring Framework 版本的最小依赖关系是 5.2.0。 +Spring Framework 版本的最小依赖关系是 5.2.0. -最小`amqp-client`Java 客户端库版本是 5.7.0。 +最小`amqp-client`Java 客户端库版本是 5.7.0. -##### [](#very-very-quick)非常,非常快 +##### 非常,非常快 这一节提供了最快的介绍。 @@ -83,7 +83,7 @@ String foo = (String) template.receiveAndConvert("myqueue"); 请注意,在本机 Java Rabbit 客户机中也有一个`ConnectionFactory`。我们在前面的代码中使用了 Spring 抽象。它缓存通道(以及可选的连接)以供重用。我们依赖于代理中的默认交换(因为在 SEND 中没有指定),以及所有队列的默认绑定到默认交换的默认名称(因此,我们可以在 SEND 中使用队列名称作为路由键)。这些行为是在 AMQP 规范中定义的。 -##### 带有 XML 配置的[](#with-xml-configuration) +##### 带有 XML 配置的 下面的示例与前面的示例相同,但将资源配置具体化为 XML: @@ -117,7 +117,7 @@ String foo = (String) template.receiveAndConvert("myqueue"); 默认情况下,``声明会自动查找类型为`Queue`、`Exchange`和`Binding`的 bean,并代表用户向代理声明它们。因此,你不需要在简单的 Java 驱动程序中显式地使用这个 Bean。有很多选项可以配置 XML 模式中组件的属性。你可以使用 XML 编辑器的自动完成功能来探索它们并查看它们的文档。 -##### 使用 Java 配置的[](#with-java-configuration) +##### 使用 Java 配置的 下面的示例重复了与前面的示例相同的示例,但使用了在 Java 中定义的外部配置: @@ -155,7 +155,7 @@ public class RabbitConfiguration { } ``` -##### [](#with-spring-boot-auto-configuration-and-an-async-pojo-listener)具有 Spring 引导自动配置和异步 POJO 侦听器 +##### 具有 Spring 引导自动配置和异步 POJO 侦听器 Spring 引导会自动配置基础设施 bean,如下例所示: @@ -185,21 +185,21 @@ public class Application { } ``` -## [](#reference)4。参考文献 +## 4.参考文献 参考文档的这一部分详细介绍了构成 Spring AMQP 的各个组件。[主要章节](#amqp)涵盖了开发 AMQP 应用程序的核心类。这一部分还包括关于[示例应用程序](#sample-apps)的一章。 -### [](#amqp)4.1。使用 Spring AMQP +### 4.1.使用 Spring AMQP 本章探讨了接口和类,它们是使用 Spring AMQP 开发应用程序所必需的组件。 -#### [](#amqp-abstractions)4.1.1。AMQP 抽象 +#### 4.1.1.AMQP 抽象 Spring AMQP 由两个模块组成(每个模块由分布中的 JAR 表示):和。“ Spring-AMQP”模块包含`org.springframework.amqp.core`包。在这个包中,你可以找到代表核心 AMQP“模型”的类。我们的目的是提供不依赖于任何特定 AMQP 代理实现或客户库的通用抽象。最终用户代码可以在供应商的实现中更具可移植性,因为它可以仅针对抽象层进行开发。然后,这些抽象由特定于代理的模块实现,例如“ Spring-Rabbit”。目前只有一个 RabbitMQ 实现。然而,除了 RabbitMQ 之外,还使用 Apache QPID 在.NET 中验证了这些抽象。由于 AMQP 在协议级别上运行,原则上,你可以将 RabbitMQ 客户机与支持相同协议版本的任何代理一起使用,但是我们目前不测试任何其他代理。 本概述假定你已经熟悉 AMQP 规范的基础知识。如果没有,请查看[其他资源](#resources)中列出的资源。 -##### [](#message)`Message` +##### `Message` 0-9-1AMQP 规范没有定义`Message`类或接口。相反,当执行`basicPublish()`之类的操作时,内容将作为字节数组参数传递,其他属性将作为单独的参数传递。 Spring AMQP 将`Message`类定义为更通用的 AMQP 域模型表示的一部分。`Message`类的目的是将主体和属性封装在一个实例中,这样 API 就可以变得更简单。下面的示例显示了`Message`类定义: @@ -230,7 +230,7 @@ public class Message { | |从版本`1.5.7`、`1.6.11`、`1.7.4`和`2.0.0`开始,如果消息体是序列化的`Serializable`Java 对象,则在执行`toString()`操作(例如在日志消息中)时,它不再被反序列化(默认情况下)。
这是为了防止不安全的反序列化。
默认情况下,只有`java.util`和`java.lang`类被反序列化。
要恢复到以前的行为,你可以通过调用`Message.addAllowedListPatterns(…​)`来添加允许的类/包模式。
支持简单的``**通配符,例如`com.something.`**`, *.MyClass`。
不能反序列化的主体在日志消息中用`byte[]`表示。| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#exchange)exchange +##### exchange `Exchange`接口表示一个 AMQP 交换,这是消息生成器发送到的内容。在代理的虚拟主机中,每个交换都有一个唯一的名称以及一些其他属性。下面的示例显示了`Exchange`接口: @@ -255,7 +255,7 @@ public interface Exchange { | |AMQP 规范还要求任何代理提供没有名称的“默认”直接交换。
所有声明的队列都绑定到默认的`Exchange`,并将其名称作为路由键。
你可以在[`AmqpTemplate`](#AMQP-template)中了解 Spring AMQP 中默认交换的使用情况。| |---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#queue)队列 +##### 队列 `Queue`类表示消息使用者从其接收消息的组件。像各种`Exchange`类一样,我们的实现旨在作为这种核心 AMQP 类型的抽象表示。下面的清单显示了`Queue`类: @@ -291,7 +291,7 @@ public class Queue { | |有关使用名称空间支持声明队列的信息,包括队列参数,请参见[配置代理](#broker-configuration)中有关队列的部分。| |---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#binding)绑定 +##### 绑定 考虑到生产者向交易所发送消息,而消费者从队列接收消息,将队列连接到交易所的绑定对于通过消息传递将生产者和消费者连接起来至关重要。在 Spring AMQP 中,我们定义了一个`Binding`类来表示这些连接。本节回顾了将队列绑定到交易所的基本选项。 @@ -326,13 +326,13 @@ Binding b = BindingBuilder.bind(someQueue).to(someTopicExchange).with("foo.*"); `AmqpTemplate`也在核心包中定义。作为实际 AMQP 消息传递所涉及的主要组件之一,它在其自己的部分中进行了详细讨论(参见[`AmqpTemplate`](#AMQP-template))。 -#### [](#connections)4.1.2。连接和资源管理 +#### 4.1.2.连接和资源管理 尽管我们在上一节中描述的 AMQP 模型是通用的,并且适用于所有实现,但是当我们进入资源管理时,细节是特定于代理实现的。因此,在本节中,我们将重点关注仅存在于我们的“ Spring-Rabbit”模块中的代码,因为在这一点上,RabbitMQ 是唯一受支持的实现。 管理到 RabbitMQ 代理的连接的中心组件是`ConnectionFactory`接口。`ConnectionFactory`实现的职责是提供`org.springframework.amqp.rabbit.connection.Connection`的实例,它是`com.rabbitmq.client.Connection`的包装器。 -##### [](#choosing-factory)选择连接工厂 +##### 选择连接工厂 有三家连接工厂可供选择。 @@ -350,7 +350,7 @@ Binding b = BindingBuilder.bind(someQueue).to(someTopicExchange).with("foo.*"); 在配置`RabbitTemplate`以使用[独立连接](#separate-connection)时,现在可以从版本 2.3.2 开始,将发布连接工厂配置为不同的类型。默认情况下,发布工厂是相同的类型,主工厂上设置的任何属性也会传播到发布工厂。 -###### [](#pooledchannelconnectionfactory)`PooledChannelConnectionFactory` +###### `PooledChannelConnectionFactory` 该工厂基于 Apache 池 2 管理单个连接和两个通道池。一个池用于事务通道,另一个池用于非事务通道。池是带有默认配置的`GenericObjectPool`s;提供了一个回调来配置池;有关更多信息,请参阅 Apache 文档。 @@ -374,11 +374,11 @@ PooledChannelConnectionFactory pcf() throws Exception { } ``` -###### [](#threadchannelconnectionfactory)`ThreadChannelConnectionFactory` +###### `ThreadChannelConnectionFactory` 这个工厂管理一个连接和两个`ThreadLocal`s,一个用于事务通道,另一个用于非事务通道。这个工厂确保同一线程上的所有操作使用相同的通道(只要它保持打开状态)。这便于在不需要[作用域操作](#scoped-operations)的情况下进行严格的消息排序。为了避免内存泄漏,如果你的应用程序使用许多短期线程,你必须调用工厂的`closeThreadChannel()`来释放通道资源。从版本 2.3.7 开始,一个线程可以将其通道传输到另一个线程。有关更多信息,请参见[多线程环境中的严格消息排序](#multi-strict)。 -###### [](#cachingconnectionfactory)`CachingConnectionFactory` +###### `CachingConnectionFactory` 提供的第三个实现是`CachingConnectionFactory`,默认情况下,它建立一个可以由应用程序共享的单个连接代理。共享连接是可能的,因为与 AMQP 进行消息传递的“工作单元”实际上是一个“通道”(在某些方面,这类似于 JMS 中的连接与会话之间的关系)。连接实例提供了`createChannel`方法。`CachingConnectionFactory`实现支持对这些通道的缓存,并且它根据通道是否是事务性的,为它们维护单独的缓存。在创建`CachingConnectionFactory`实例时,可以通过构造函数提供“hostname”。你还应该提供“用户名”和“密码”属性。要配置通道缓存的大小(默认为 25),可以调用`setChannelCacheSize()`方法。 @@ -394,7 +394,7 @@ PooledChannelConnectionFactory pcf() throws Exception { 重要的是要理解,缓存大小(默认情况下)不是一个限制,而仅仅是可以缓存的通道数量。如果缓存大小为 10,那么实际上可以使用任意数量的通道。如果使用了超过 10 个通道,并且它们都返回到缓存中,则在缓存中使用 10 个。其余部分是封闭的。 -从 1.6 版本开始,默认通道缓存大小从 1 增加到 25。在大容量、多线程的环境中,较小的缓存意味着以较高的速率创建和关闭通道。增加默认的缓存大小可以避免这种开销。你应该通过 RabbitMQ 管理 UI 监视正在使用的通道,并且如果你看到许多通道正在创建和关闭,请考虑进一步增加缓存大小。缓存仅按需增长(以满足应用程序的并发性需求),因此此更改不会影响现有的低容量应用程序。 +从 1.6 版本开始,默认通道缓存大小从 1 增加到 25.在大容量、多线程的环境中,较小的缓存意味着以较高的速率创建和关闭通道。增加默认的缓存大小可以避免这种开销。你应该通过 RabbitMQ 管理 UI 监视正在使用的通道,并且如果你看到许多通道正在创建和关闭,请考虑进一步增加缓存大小。缓存仅按需增长(以满足应用程序的并发性需求),因此此更改不会影响现有的低容量应用程序。 从版本 1.4.2 开始,`CachingConnectionFactory`具有一个名为`channelCheckoutTimeout`的属性。当此属性大于零时,`channelCacheSize`将成为连接上可以创建的通道数量的限制。如果达到限制,则调用线程块,直到通道可用或达到超时为止,在这种情况下,将抛出`AmqpTimeoutException`。 @@ -431,7 +431,7 @@ Connection connection = connectionFactory.createConnection(); ``` -在大多数情况下,这种方法更可取,因为框架可以为你选择最好的默认值。创建的实例是`CachingConnectionFactory`。请记住,通道的默认缓存大小是 25。如果你希望有更多的通道是 cachedm,那么可以通过设置“channelcachesize”属性来设置一个更大的值。在 XML 中,它将如下所示: +在大多数情况下,这种方法更可取,因为框架可以为你选择最好的默认值。创建的实例是`CachingConnectionFactory`。请记住,通道的默认缓存大小是 25.如果你希望有更多的通道是 cachedm,那么可以通过设置“channelcachesize”属性来设置一个更大的值。在 XML 中,它将如下所示: ``` ``` -##### [](#addressresolver)addresolver +##### addresolver 从版本 2.1.15 开始,你现在可以使用`AddressResover`来解析连接地址。这将覆盖`addresses`和`host/port`属性的任何设置。 -##### [](#naming-connections)命名连接 +##### 命名连接 从版本 1.7 开始,为注入`AbstractionConnectionFactory`提供了一个`ConnectionNameStrategy`。生成的名称用于特定于应用程序的目标 RabbitMQ 连接的标识。如果 RabbitMQ 服务器支持该连接名,则会在管理 UI 中显示该连接名。这个值不一定是唯一的,也不能用作连接标识符——例如,在 HTTPAPI 请求中。这个值应该是人类可读的,并且是`connection_name`键下`ClientProperties`的一部分。你可以使用一个简单的 lambda,如下所示: @@ -521,7 +521,7 @@ public ConnectionFactory rabbitConnectionFactory(ConnectionNameStrategy cns) { | |当使用 Spring 引导及其自动配置的连接工厂时,只需要声明`ConnectionNameStrategy``@Bean`。
引导自动检测 Bean 并将其连接到工厂。| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#blocked-connections-and-resource-constraints)阻塞的连接和资源约束 +##### 阻塞的连接和资源约束 与[内存闹钟](https://www.rabbitmq.com/memory.html)对应的代理可能会阻止连接以进行交互。从版本 2.0 开始,`org.springframework.amqp.rabbit.connection.Connection`可以提供`com.rabbitmq.client.BlockedListener`实例,以通知连接阻塞和未阻塞事件。此外,`AbstractConnectionFactory`分别通过其内部的`BlockedListener`实现了`ConnectionBlockedEvent`和`ConnectionUnblockedEvent`。这些允许你提供应用程序逻辑,以便对代理上的问题做出适当的反应,并(例如)采取一些纠正措施。 @@ -532,7 +532,7 @@ public ConnectionFactory rabbitConnectionFactory(ConnectionNameStrategy cns) { 从版本 1.7.7 开始,将提供一个`AmqpResourceNotAvailableException`,当`SimpleConnection.createChannel()`无法创建`Channel`时,将抛出该参数(例如,因为已达到`channelMax`限制,并且缓存中没有可用通道)。你可以在`RetryPolicy`中使用此异常来恢复一些后退后的操作。 -##### [](#connection-factory)配置底层客户端连接工厂 +##### 配置底层客户端连接工厂 `CachingConnectionFactory`使用了 Rabbit 客户机`ConnectionFactory`的实例。在`CachingConnectionFactory`上设置等效属性时,会传递许多配置属性(例如`host, port, userName, password, requestedHeartBeat, and connectionTimeout`)。要设置其他属性(例如`clientProperties`),你可以定义 Rabbit Factory 的实例,并使用`CachingConnectionFactory`的适当构造函数提供对它的引用。当使用名称空间([如前所述](#connections))时,你需要在`connection-factory`属性中提供对已配置工厂的引用。为了方便起见,提供了工厂 Bean 以协助在 Spring 应用程序上下文中配置连接工厂,如[下一节](#rabbitconnectionfactorybean-configuring-ssl)中所讨论的。 @@ -544,7 +544,7 @@ public ConnectionFactory rabbitConnectionFactory(ConnectionNameStrategy cns) { | |4.0.x 客户端默认支持自动恢复。
虽然与此功能兼容, Spring AMQP 有自己的恢复机制,通常不需要客户端恢复功能。
我们建议禁用`amqp-client`自动恢复,为了避免在代理可用但连接尚未恢复时获得`AutoRecoverConnectionNotCurrentlyOpenException`实例,你可能会注意到此异常,例如,当`RetryTemplate`在`RabbitTemplate`中配置了`RetryTemplate`时,
由于自动恢复连接在定时器上恢复,因此可以通过使用 Spring AMQP 的恢复机制更快地恢复连接,
从 1.7.1 版本开始, Spring AMQP 禁用`amqp-client`自动恢复,除非你显式地创建自己的 RabbitMQ 连接工厂并将其提供给`CachingConnectionFactory`。
RabbitMQ`ConnectionFactory`由`RabbitConnectionFactoryBean`创建的实例还具有默认禁用的选项。| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#rabbitconnectionfactorybean-configuring-ssl)`RabbitConnectionFactoryBean`和配置 SSL +##### `RabbitConnectionFactoryBean`和配置 SSL 从版本 1.4 开始,提供了一个方便的`RabbitConnectionFactoryBean`,以便通过使用依赖项注入在底层客户机连接工厂上方便地配置 SSL 属性。其他设置者将委托给底层工厂。以前,你必须以编程方式配置 SSL 选项。下面的示例展示了如何配置`RabbitConnectionFactoryBean`: @@ -584,7 +584,7 @@ trustStore.passPhrase=secret | |从版本 2.2.5 开始,工厂 Bean 默认情况下将始终使用 TLSv1.2;以前,它在某些情况下使用 v1.1,在其他情况下使用 v1.2(取决于其他属性)。如果出于某种原因需要使用 v1.1,请设置属性:。| |---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#cluster)连接到集群 +##### 连接到集群 要连接到群集,请在`CachingConnectionFactory`上配置`addresses`属性: @@ -609,7 +609,7 @@ public CachingConnectionFactory ccf() { } ``` -##### [](#routing-connection-factory)路由连接工厂 +##### 路由连接工厂 从 1.3 版本开始,引入了`AbstractRoutingConnectionFactory`。这个工厂提供了一种机制来配置几个`ConnectionFactories`的映射,并在运行时通过一些`lookupKey`确定一个目标`ConnectionFactory`。通常,实现会检查线程绑定的上下文。为了方便起见, Spring AMQP 提供了`SimpleRoutingConnectionFactory`,它从`SimpleResourceHolder`获得当前线程绑定的`lookupKey`。以下示例展示了如何在 XML 和 Java 中配置`SimpleRoutingConnectionFactory`: @@ -659,7 +659,7 @@ public class MyService { | |目标(如果提供的话,也是默认的)连接工厂必须具有相同的 Publisher 确认和返回设置。
参见[发布者确认并返回](#cf-pub-conf-ret)。| |---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#queue-affinity)队列亲和性和`LocalizedQueueConnectionFactory` +##### 队列亲和性和`LocalizedQueueConnectionFactory` 在集群中使用 HA 队列时,为了获得最佳性能,你可能希望连接到领先队列所在的物理代理。`CachingConnectionFactory`可以配置多个代理地址。这是故障转移,客户端尝试按顺序连接。`LocalizedQueueConnectionFactory`使用管理插件提供的 REST API 来确定哪个节点是队列的领头节点。然后,它创建(或从缓存检索)一个`CachingConnectionFactory`,该节点仅连接到该节点。如果连接失败,则确定新的引导节点,并由使用者连接到该节点。`LocalizedQueueConnectionFactory`配置了默认的连接工厂,以防无法确定队列的物理位置,在这种情况下,它将正常地连接到集群。 @@ -704,7 +704,7 @@ public LocalizedQueueConnectionFactory queueAffinityCF( 注意,前三个参数是`addresses`、`adminUris`和`nodes`的数组。这些位置在于,当容器试图连接到队列时,它使用 Admin API 来确定哪个节点是队列的领导者,并以与该节点相同的阵列位置连接到该地址。 -##### [](#cf-pub-conf-ret)发布者确认并返回 +##### 发布者确认并返回 通过将`CachingConnectionFactory`属性`publisherConfirmType`设置为`ConfirmType.CORRELATED`,并将`publisherReturns`属性设置为“true”,可以支持确认(具有相关性)和返回的消息。 @@ -715,7 +715,7 @@ public LocalizedQueueConnectionFactory queueAffinityCF( | |有关更多的背景信息,请参见 RabbitMQ 团队的博客文章[介绍出版商确认](https://www.rabbitmq.com/blog/2011/02/10/introducing-publisher-confirms/)。| |---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#connection-channel-listeners)连接和通道侦听器 +##### 连接和通道侦听器 连接工厂支持注册`ConnectionListener`和`ChannelListener`实现。这允许你接收关于连接和通道相关事件的通知。(`ConnectionListener`用于`RabbitAdmin`在建立连接时执行声明-有关更多信息,请参见[交换、队列和绑定的自动声明](#automatic-declaration))。下面的清单显示了`ConnectionListener`接口定义: @@ -750,7 +750,7 @@ public interface ChannelListener { 关于可能需要注册`ChannelListener`的一种情况,请参见[发布是异步的——如何检测成功和失败](#publishing-is-async)。 -##### [](#channel-close-logging)记录通道关闭事件 +##### 记录通道关闭事件 版本 1.5 引入了一种机制,使用户能够控制日志记录级别。 @@ -768,7 +768,7 @@ public interface ChannelListener { 另见[消费者活动](#consumer-events)。 -##### [](#runtime-cache-properties)运行时缓存属性 +##### 运行时缓存属性 从版本 1.6 开始,`CachingConnectionFactory`现在通过`getCacheProperties()`方法提供缓存统计信息。这些统计信息可用于优化缓存,以在生产中对其进行优化。例如,可以使用高水位标记来确定是否应该增加缓存大小。如果它等于缓存大小,你可能需要考虑进一步增加。下表描述了`CacheMode.CHANNEL`属性: @@ -801,16 +801,16 @@ public interface ChannelListener { ![cacheStats](images/cacheStats.png) -图 1。JVisualVM 示例 +图 1.JVisualVM 示例 -##### [](#auto-recovery)RabbitMQ 自动连接/拓扑恢复 +##### RabbitMQ 自动连接/拓扑恢复 自 Spring AMQP 的第一个版本以来,该框架已经在代理失败的情况下提供了自己的连接和通道恢复。同样,如[配置代理](#broker-configuration)中所讨论的,`RabbitAdmin`在重新建立连接时重新声明任何基础设施 bean(队列和其他)。因此,它不依赖现在由`amqp-client`库提供的[自动恢复](https://www.rabbitmq.com/api-guide.html#recovery)。 Spring AMQP 现在使用`4.0.x`的`amqp-client`版本,该版本在默认情况下具有启用的自动恢复功能。 Spring 如果你愿意,AMQP 仍然可以使用其自己的恢复机制,在客户端中禁用它,(通过将底层`automaticRecoveryEnabled`上的`RabbitMQ connectionFactory`属性设置为`false`)。然而,该框架与启用的自动恢复完全兼容。这意味着你在代码中创建的任何消费者(可能通过`RabbitTemplate.execute()`)都可以自动恢复。 | |只有被定义为 bean 的元素(队列、交换、绑定)在连接失败后才会重新声明。
直接从用户代码调用`RabbitAdmin.declare*()`方法声明的元素对于框架来说是未知的,因此无法恢复。
如果你需要变量数量的声明,考虑定义类型`Declarables`的 Bean 或 bean,如[声明交换、队列和绑定的集合](#collection-declaration)中讨论的那样。| |---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#custom-client-props)4.1.3。添加自定义客户端连接属性 +#### 4.1.3.添加自定义客户端连接属性 现在,`CachingConnectionFactory`允许你访问底层连接工厂,以允许例如设置自定义客户机属性。下面的示例展示了如何做到这一点: @@ -820,7 +820,7 @@ connectionFactory.getRabbitConnectionFactory().getClientProperties().put("thing1 当查看连接时,这些属性会出现在 RabbitMQ 管理 UI 中。 -#### [](#amqp-template)4.1.4。`AmqpTemplate` +#### 4.1.4.`AmqpTemplate` 与 Spring 框架和相关项目提供的许多其他高级抽象一样, Spring AMQP 提供了一个发挥核心作用的“模板”。定义主要操作的接口称为`AmqpTemplate`。这些操作涵盖了发送和接收消息的一般行为。换句话说,它们不是任何实现所独有的——因此名称中的“AMQP”。另一方面,该接口的一些实现与 AMQP 协议的实现相关联。与 JMS 本身是一个接口级 API 不同,AMQP 是一个线路级协议。该协议的实现提供了自己的客户端库,因此模板接口的每个实现都依赖于特定的客户端库。目前,只有一个实现:`RabbitTemplate`。在下面的示例中,我们经常使用`AmqpTemplate`。然而,当你查看配置示例或在其中实例化模板或调用 setter 的任何代码摘录时,你可以看到实现类型(例如,`RabbitTemplate`)。 @@ -828,7 +828,7 @@ connectionFactory.getRabbitConnectionFactory().getClientProperties().put("thing1 另见[异步兔子模板](#async-template)。 -##### [](#template-retry)添加重试功能 +##### 添加重试功能 从版本 1.3 开始,你现在可以将`RabbitTemplate`配置为使用`RetryTemplate`来帮助处理代理连接问题。有关完整信息,请参见[spring-retry](https://github.com/spring-projects/spring-retry)项目。下面只是一个使用指数后退策略和默认`SimpleRetryPolicy`的示例,它在向调用方抛出异常之前进行了三次尝试。 @@ -895,7 +895,7 @@ retryTemplate.execute( 在这种情况下,将**不是**将`RetryTemplate`注入到`RabbitTemplate`中。 -##### [](#publishing-is-async)发布是异步的——如何检测成功和失败 +##### 发布是异步的——如何检测成功和失败 发布消息是一种异步机制,默认情况下,RabbitMQ 会删除无法路由的消息。对于成功的发布,你可以收到异步确认,如[相关发布者确认并返回](#template-confirms)中所述。考虑两种失败场景: @@ -926,7 +926,7 @@ this.connectionFactory.addConnectionListener(new ConnectionListener() { 要检测发送线程上的异常,可以在`RabbitTemplate`上检测`setChannelTransacted(true)`,并在`txCommit()`上检测异常。但是,**交易大大妨碍了业绩。**,因此在仅为这个用例启用事务之前,请仔细考虑这一点。 -##### [](#template-confirms)相关发布者确认并返回 +##### 相关发布者确认并返回 `RabbitTemplate`的`AmqpTemplate`实现支持 Publisher 确认和返回。 @@ -986,7 +986,7 @@ assertTrue(cd1.getFuture().get(10, TimeUnit.SECONDS).isAck()); 另请参见[作用域操作](#scoped-operations),以获得等待发布者确认的更简单机制。 -##### [](#scoped-operations)作用域操作 +##### 作用域操作 通常,当使用模板时,一个`Channel`将从缓存中签出(或创建),用于操作,并返回到缓存中进行重用。在多线程环境中,不能保证下一个操作使用相同的通道。然而,有时你可能希望对通道的使用有更多的控制,并确保多个操作都在同一个通道上执行。 @@ -1049,7 +1049,7 @@ Boolean result = this.template.invoke(t -> { | |作用域操作绑定到线程。
有关多线程环境中严格排序的讨论,请参见[多线程环境中的严格消息排序](#multi-strict)。| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#multi-strict)多线程环境中的严格消息排序 +##### 多线程环境中的严格消息排序 [作用域操作](#scoped-operations)中的讨论仅在同一线程上执行操作时才适用。 @@ -1223,7 +1223,7 @@ class Service { | |一旦调用`prepareSwitchContext`,如果当前线程执行更多的操作,它们将在新的通道上执行。
当不再需要线程绑定通道时,关闭该通道非常重要。| |---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#template-messaging)消息传递集成 +##### 消息传递集成 从版本 1.4 开始,`RabbitMessagingTemplate`(构建在`RabbitTemplate`之上)提供了与 Spring Framework 消息传递抽象的集成——即`org.springframework.messaging.Message`。这允许你通过使用`spring-messaging``Message`抽象来发送和接收消息。这个抽象被其他 Spring 项目所使用,例如 Spring 集成和 Spring 的 STOMP 支持。涉及两个消息转换器:一个用于在 Spring-messaging`Message`和 Spring AMQP 的`Message`抽象之间进行转换,另一个用于在 Spring AMQP 的`Message`抽象和底层 RabbitMQ 客户端库所需的格式之间进行转换。默认情况下,消息有效负载由提供的`RabbitTemplate`实例的消息转换器进行转换。或者,可以将自定义`MessagingMessageConverter`与其他有效负载转换器一起注入,如下例所示: @@ -1233,7 +1233,7 @@ amqpMessageConverter.setPayloadConverter(myPayloadConverter); rabbitMessagingTemplate.setAmqpMessageConverter(amqpMessageConverter); ``` -##### [](#template-user-id)验证用户 ID +##### 验证用户 ID 从版本 1.6 开始,模板现在支持`user-id-expression`(使用 Java 配置时`userIdExpression`)。如果发送了消息,则在计算该表达式后设置 User ID 属性(如果尚未设置)。评估的根对象是要发送的消息。 @@ -1247,14 +1247,14 @@ rabbitMessagingTemplate.setAmqpMessageConverter(amqpMessageConverter); 第一个例子是一个字面表达式。第二个从应用程序上下文中的连接工厂 Bean 获得`username`属性。 -##### [](#separate-connection)使用单独的连接 +##### 使用单独的连接 从版本 2.0.2 开始,你可以将`usePublisherConnection`属性设置为`true`,以便在可能的情况下使用与侦听器容器使用的不同的连接。这是为了避免当生产者由于任何原因而被封锁时,消费者被封锁。为此目的,连接工厂维护第二个内部连接工厂;默认情况下,它与主工厂的类型相同,但是如果你希望使用不同的工厂类型进行发布,则可以明确地设置该类型。如果 Rabbit 模板在侦听器容器启动的事务中运行,则使用容器的通道,而不考虑此设置。 | |通常,你不应该在模板中使用`RabbitAdmin`,而该模板将此设置为`true`。
使用获取连接工厂的`RabbitAdmin`构造函数。
如果你使用另一个获取模板的构造函数,请确保模板的属性为`false`。
这是因为,通常,管理员用于声明侦听器容器的队列。
使用属性设置为`true`的模板将意味着在与侦听器容器使用的连接不同的连接上声明排他队列(例如`AnonymousQueue`)。,在这种情况下,
,容器不能使用队列。| |---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#sending-messages)4.1.5。发送消息 +#### 4.1.5.发送消息 在发送消息时,可以使用以下任何一种方法: @@ -1303,7 +1303,7 @@ template.setRoutingKey("queue.helloWorld"); // but we'll always send to this Que template.send(new Message("Hello World".getBytes(), someProperties)); ``` -##### [](#message-builder)Message Builder API +##### Message Builder API 从版本 1.3 开始,消息生成器 API 由`MessageBuilder`和`MessagePropertiesBuilder`提供。这些方法为创建消息或消息属性提供了一种方便的“fluent”方法。以下示例展示了 Fluent API 的实际应用: @@ -1380,7 +1380,7 @@ Message postProcessMessage(Message message, Correlation correlation); CorrelationData postProcess(Message message, CorrelationData correlationData); ``` -##### [](#publisher-returns)Publisher 返回 +##### Publisher 返回 当模板的`mandatory`属性是`true`时,返回的消息由[`AmqpTemplate`]中描述的回调提供。 @@ -1388,7 +1388,7 @@ CorrelationData postProcess(Message message, CorrelationData correlationData); 在发送和接收操作中,`RabbitTemplate`还可以在内部使用发布服务器返回。有关更多信息,请参见[回复超时](#reply-timeout)。 -##### [](#template-batching)批处理 +##### 批处理 版本 1.4.2 引入了`BatchingRabbitTemplate`。这是`RabbitTemplate`的一个子类,具有一个重写的`send`方法,该方法根据`BatchingStrategy`批处理消息。只有当批处理完成时,消息才会发送到 RabbitMQ。下面的清单显示了`BatchingStrategy`接口定义: @@ -1422,11 +1422,11 @@ a`SimpleBatchingStrategy`。它支持将消息发送到单个 Exchange 或 Routi 但是,有关更多信息,请参见[@RabbitListener 与批处理](#receiving-batch)。 -#### [](#receiving-messages)4.1.6。接收消息 +#### 4.1.6.接收消息 消息接收总是比发送复杂一点。有两种方法可以接收`Message`。更简单的选项是使用轮询方法调用一次轮询一个`Message`。更复杂但更常见的方法是注册一个侦听器,该侦听器异步地按需接收`Messages`。在接下来的两个子节中,我们将考虑每种方法的示例。 -##### [](#polling-consumer)轮询消费者 +##### 轮询消费者 `AmqpTemplate`本身可以用于对`Message`的接收进行民意测验。默认情况下,如果没有可用的消息,`null`将立即返回。不存在阻塞。从版本 1.5 开始,你可以设置`receiveTimeout`,以毫秒为单位,并且 ReceiveMethods 块等待消息的时间最长可达那么长。小于零的值意味着无限期地阻塞(或至少直到与代理的连接丢失为止)。版本 1.6 引入了`receive`方法的变体,这些方法允许在每次调用时传入超时。 @@ -1502,7 +1502,7 @@ if (received) { } ``` -##### [](#async-consumer)异步消费者 +##### 异步消费者 | |Spring AMQP 还通过使用`@RabbitListener`注释来支持带注释的侦听器端点,并提供一个开放的基础设施来以编程方式注册端点。
这是迄今为止设置异步消费者的最方便的方式。
有关更多详细信息,请参见[注释驱动的监听器端点](#async-annotation-driven)。| |---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| @@ -1510,7 +1510,7 @@ if (received) { | |预取默认值过去是 1,这可能会导致有效的使用者利用率不足,
从版本 2.0 开始,默认的预取值现在是 250,这应该会使使用者在大多数常见的情况下都很忙,
因此提高了吞吐量。,尽管如此,仍然存在,预取值应该较低的场景:对于大消息,

*,特别是如果处理速度较慢(消息在客户端进程中可能会增加大量内存)

* 当需要严格的消息排序时(在这种情况下,预取值应设置为 1)

* 其他特殊情况

同样,对于低容量的消息传递和多个消费者(包括单个侦听器容器实例中的并发性),你可能希望减少预取,以便在消费者之间获得更均匀的消息分布。

关于预取的更多背景信息,请参见[消息侦听器容器配置](#containerAttributes)。`x-expires`
,请参阅这篇关于[RabbitMQ 中的消费者利用](https://www.rabbitmq.com/blog/2014/04/14/finding-bottlenecks-with-rabbitmq-3-3/)的文章和这篇关于[排队论](https://www.rabbitmq.com/blog/2012/05/11/some-queuing-theory-throughput-latency-and-bandwidth/)的文章。| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -###### [](#message-listener)消息侦听器 +###### 消息侦听器 对于异步`Message`接收,涉及一个专用组件(而不是`AmqpTemplate`)。该组件是用于`Message`消费回调的容器。在本节的后面部分,我们将考虑容器及其属性。不过,首先我们应该看看回调,因为这是应用程序代码与消息传递系统集成的地方。回调有几个选项,从`MessageListener`接口的实现开始,下面的清单显示了这个选项: @@ -1531,7 +1531,7 @@ public interface ChannelAwareMessageListener { | |在版本 2.1 中,此接口从包`o.s.amqp.rabbit.core`移动到`o.s.amqp.rabbit.listener.api`。| |---|-----------------------------------------------------------------------------------------------------------| -###### [](#message-listener-adapter)`MessageListenerAdapter` +###### `MessageListenerAdapter` 如果希望在应用程序逻辑和消息传递 API 之间保持更严格的分离,则可以依赖框架提供的适配器实现。这通常被称为“消息驱动的 POJO”支持。 @@ -1592,7 +1592,7 @@ public void handleMessage(Object object, Channel channel, Message message) throw } ``` -###### [](#container)容器 +###### 容器 既然你已经看到了`ChannelAwareMessageListener`-listening 回调的各种选项,那么我们就可以将注意力转向容器了。基本上,容器处理“主动”职责,以便侦听器回调可以保持被动。容器是“生命周期”组件的一个示例。它提供了启动和停止的方法。在配置容器时,实质上是在 AMQP 队列和`MessageListener`实例之间建立桥梁。你必须提供对`ConnectionFactory`的引用,以及该侦听器应该从其中使用消息的队列名称或队列实例。 @@ -1660,7 +1660,7 @@ public class ExampleAmqpConfiguration { } ``` -###### [](#consumer-priority)消费者优先权 +###### 消费者优先权 从 RabbitMQ3.2 版本开始,代理现在支持消费者优先权(参见[使用 RabbitMQ 的消费者优先级](https://www.rabbitmq.com/blog/2013/12/16/using-consumer-priorities-with-rabbitmq/))。这可以通过在消费者上设置`x-priority`参数来实现。`SimpleMessageListenerContainer`现在支持设置消费者参数,如下例所示: @@ -1679,7 +1679,7 @@ container.setConsumerArguments(Collections. 从版本 1.3 开始,你可以修改容器在运行时监听的队列。见[监听器容器队列](#listener-queues)。 -###### [](#lc-auto-delete)`auto-delete`队列 +###### `auto-delete`队列 当容器被配置为侦听`auto-delete`队列时,队列具有`x-expires`选项,或者在代理上配置了[活着的时间](https://www.rabbitmq.com/ttl.html)策略,当容器停止时(即最后一个使用者被取消时),代理将队列删除。在版本 1.3 之前,由于缺少队列,无法重新启动容器。`RabbitAdmin`仅在连接关闭或打开时自动重新声明队列,以此类推,而在停止和启动容器时不会发生这种情况。 @@ -1706,7 +1706,7 @@ container.setConsumerArguments(Collections. 在这种情况下,队列和交换由`containerAdmin`声明,其具有,因此在上下文初始化期间不会声明元素。同样,由于同样的原因,容器没有启动。当容器稍后被启动时,它使用其对`containerAdmin`的引用来声明元素。 -##### [](#de-batching)批处理消息 +##### 批处理消息 批处理的消息(由生成者创建)由侦听器容器(使用`springBatchFormat`消息头)自动进行去批处理。拒绝批处理中的任何消息都会导致整个批处理被拒绝。有关批处理的更多信息,请参见[Batching](#template-batching)。 @@ -1714,7 +1714,7 @@ container.setConsumerArguments(Collections. 设置容器属性`consumerBatchEnabled`以启用此功能。`deBatchingEnabled`也必须为真,以便容器负责处理这两种类型的批。当`consumerBatchEnabled`为真时实现`BatchMessageListener`或`ChannelAwareBatchMessageListener`。从版本 2.2.7 开始,`SimpleMessageListenerContainer`和`DirectMessageListenerContainer`都可以将[生产者创建了批](#template-batching)删除为`List`。有关在`@RabbitListener`中使用此功能的信息,请参见`DirectMessageListenerContainer`。 -##### [](#consumer-events)消费者活动 +##### 消费者活动 容器在侦听器(使用者)遇到某种故障时发布应用程序事件。事件`ListenerContainerConsumerFailedEvent`具有以下属性: @@ -1751,7 +1751,7 @@ container.setConsumerArguments(Collections. * [检测空闲异步消费者](#idle-containers):检测到缺少队列时。 -##### [](#consumerTags)消费者标签 +##### 消费者标签 你可以提供一种生成消费者标签的策略。默认情况下,消费者标记是由代理生成的。下面的清单显示了`ConsumerTagStrategy`接口定义: @@ -1767,7 +1767,7 @@ public interface ConsumerTagStrategy { 见[消息侦听器容器配置](#containerAttributes)。 -##### [](#async-annotation-driven)注释驱动的侦听器端点 +##### 注释驱动的侦听器端点 异步接收消息的最简单方法是使用带注释的侦听器端点基础结构。简而言之,它允许你将托管 Bean 方法公开为 Rabbit 侦听器端点。下面的示例展示了如何使用`@RabbitListener`注释: @@ -1863,7 +1863,7 @@ public String handleWithHeadersExchange(String foo) { 如果名称解析为`null`或空的`String`,则忽略`@Argument`。 -###### [](#meta-annotation-driven)元注解 +###### 元注解 有时你可能希望对多个侦听器使用相同的配置。为了减少样板配置,你可以使用元注释来创建自己的侦听器注释。下面的示例展示了如何做到这一点: @@ -1924,7 +1924,7 @@ static @interface MyListeners { } ``` -###### [](#async-annotation-driven-enable)启用侦听器端点注释 +###### 启用侦听器端点注释 要启用对`@RabbitListener`注释的支持,你可以将`@EnableRabbit`添加到你的一个`@Configuration`类中。下面的示例展示了如何做到这一点: @@ -2022,7 +2022,7 @@ public void manual1(String in, Channel channel, } ``` -###### [](#async-annotation-conversion)带注释方法的消息转换 +###### 带注释方法的消息转换 在调用侦听器之前,管道中有两个转换步骤。第一步使用`MessageConverter`将传入的 Spring AMQP`Message`转换为 Spring-messaging`Message`。当调用目标方法时,如果需要,消息有效负载将被转换为方法参数类型。 @@ -2108,7 +2108,7 @@ public class AppConfig implements RabbitListenerConfigurer { | |对于多方法侦听器(参见[多方法侦听器](#annotation-method-selection)),方法选择是基于消息的有效负载**消息转换后**。
只有在方法已被选择之后才调用方法参数转换器。| |---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -###### [](#custom-argument-resolver)向 @RabbitListener 添加自定义`HandlerMethodArgumentResolver` +###### 向 @RabbitListener 添加自定义`HandlerMethodArgumentResolver` 从版本 2.3.7 开始,你可以添加自己的`HandlerMethodArgumentResolver`并解析自定义方法参数。你所需要的只是实现`ClassMapper`并使用来自类`RabbitListenerEndpointRegistrar`的方法`setCustomMethodArgumentResolvers()`。 @@ -2141,7 +2141,7 @@ class CustomRabbitConfig implements RabbitListenerConfigurer { } ``` -###### [](#async-annotation-driven-registration)程序化端点注册 +###### 程序化端点注册 `RabbitListenerEndpoint`提供了一个 Rabbit 端点的模型,并负责为该模型配置容器。除了通过`RabbitListener`注释检测到的端点之外,该基础结构还允许你以编程方式配置端点。下面的示例展示了如何做到这一点: @@ -2166,7 +2166,7 @@ public class AppConfig implements RabbitListenerConfigurer { 需要注意的是,你也可以完全跳过`@RabbitListener`的使用,并通过`RabbitListenerConfigurer`以编程方式注册端点。 -###### [](#async-annotation-driven-enable-signature)带注释的端点方法签名 +###### 带注释的端点方法签名 到目前为止,我们已经在我们的端点中注入了一个简单的`String`,但是它实际上可以有一个非常灵活的方法签名。下面的示例重写它,以使用自定义标头注入`Order`: @@ -2230,7 +2230,7 @@ public class AppConfig implements RabbitListenerConfigurer { } ``` -###### [](#rabbit-validation)@rabbitlistener@payload validation +###### @rabbitlistener@payload validation 从版本 2.3.7 开始,现在更容易添加`Validator`来验证`@RabbitListener`和`@RabbitHandler``@Payload`参数。现在,你只需将验证器添加到注册商本身即可。 @@ -2294,7 +2294,7 @@ public RabbitListenerErrorHandler validationErrorHandler() { } ``` -###### [](#annotation-multiple-queues)监听多个队列 +###### 监听多个队列 当你使用`queues`属性时,你可以指定关联的容器可以侦听多个队列。你可以使用`@Header`注释使 POJO 方法可以使用接收消息的队列名称。下面的示例展示了如何做到这一点: @@ -2326,7 +2326,7 @@ public class MyService { 在版本 1.5 之前,只能以这种方式指定单个队列。每个队列都需要一个单独的属性。 -###### [](#async-annotation-driven-reply)回复管理 +###### 回复管理 `MessageListenerAdapter`中现有的支持已经允许你的方法具有一个非 void 返回类型。在这种情况下,调用的结果被封装在一条消息中,发送到原始消息的`ReplyToAddress`头中指定的地址,或发送到侦听器上配置的默认地址。你可以通过使用消息抽象的`@SendTo`注释来设置默认地址。 @@ -2445,7 +2445,7 @@ public String listen(Message in) { } ``` -###### [](#reply-content-type)回复 ContentType +###### 回复 ContentType 如果使用复杂的消息转换器,例如`ContentTypeDelegatingMessageConverter`,则可以通过在侦听器上设置`replyContentType`属性来控制回复的内容类型。这允许转换器为应答选择适当的委托转换器。 @@ -2483,7 +2483,7 @@ public Message listen(String in) { 此内容类型将在`MessageProperties`中传递给转换器。默认情况下,为了向后兼容,转换器设置的任何内容类型属性在转换后都将被这个值覆盖。如果你希望重写该行为,还可以将`AmqpHeaders.CONTENT_TYPE_CONVERTER_WINS`设置为`true`,并且转换器设置的任何值都将被保留。 -###### [](#annotation-method-selection)多方法侦听器 +###### 多方法侦听器 从版本 1.5.0 开始,你可以在类级别上指定`@RabbitListener`注释。与新的`@RabbitHandler`注释一起,这允许单个侦听器根据传入消息的有效负载类型调用不同的方法。这一点最好用一个例子来描述: @@ -2522,11 +2522,11 @@ public class MultiListenerBean { | |`@RabbitHandler`仅用于处理转换后的消息负载,如果希望接收未转换的 RAW`Message`对象,则必须在方法上使用`@RabbitListener`,而不是在类上。| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -###### [](#repeatable-rabbit-listener)`@Repeatable` `@RabbitListener` +###### `@Repeatable` `@RabbitListener` 从版本 1.6 开始,`@RabbitListener`注释被标记为`@Repeatable`。这意味着注释可以多次出现在相同的注释元素(方法或类)上。在这种情况下,将为每个注释创建一个单独的侦听器容器,每个注释都调用相同的侦听器`@Bean`。可重复的注释可以用于 Java8 或更高版本。 -###### [](#proxy-rabbitlistener-and-generics)代理`@RabbitListener`和泛型 +###### 代理`@RabbitListener`和泛型 如果你的服务旨在被代理(例如,在`@Transactional`的情况下),那么当接口具有通用参数时,你应该记住一些考虑因素。考虑以下示例: @@ -2563,7 +2563,7 @@ static class TxServiceImpl implements TxService { } ``` -###### [](#annotation-error-handling)处理异常 +###### 处理异常 默认情况下,如果一个带注释的侦听器方法抛出一个异常,它将被抛出到容器,消息将被重新请求并重新交付、丢弃或路由到死信交换,这取决于容器和代理配置。任何东西都不会退还给寄件人。 @@ -2607,7 +2607,7 @@ public Object handleError(Message amqpMessage, org.springframework.messaging.Mes 从版本 2.2.18 开始,如果抛出消息转换异常,将调用错误处理程序,在`message`参数中使用`null`。这允许应用程序向调用者发送一些结果,表明收到了格式错误的消息。以前,此类错误是由容器抛出和处理的。 -###### [](#container-management)容器管理 +###### 容器管理 为注释创建的容器未在应用程序上下文中注册。你可以通过在`RabbitListenerEndpointRegistry` Bean 上调用`getListenerContainers()`来获得所有容器的集合。然后可以迭代这个集合,例如,停止或启动所有容器,或者调用注册表本身上的`Lifecycle`方法,这些方法将调用每个容器上的操作。 @@ -2617,7 +2617,7 @@ public Object handleError(Message amqpMessage, org.springframework.messaging.Mes 从版本 1.5 开始,你现在可以将`group`分配到`RabbitListener`端点上的容器。这提供了一种机制来获取对容器子集的引用。添加一个`group`属性会导致类型`Collection`的 Bean 被注册到带有组名的上下文中。 -##### [](#receiving-batch)@rabbitlistener with batching +##### @rabbitlistener with batching 当接收到[a batch](#template-batching)的消息时,解批处理通常由容器执行,侦听器在一次调用一条消息。从版本 2.2 开始,你可以将侦听器容器工厂和侦听器配置为在一个调用中接收整个批处理,只需设置工厂的`batchListener`属性,并将方法有效负载参数设置为`List`: @@ -2694,7 +2694,7 @@ public void consumerBatch3(List strings) { 还可以添加`Channel`参数,该参数在使用`MANUAL`ACK 模式时经常使用。这在第三个示例中不是很有用,因为你无法访问`delivery_tag`属性。 -##### [](#using-container-factories)使用容器工厂 +##### 使用容器工厂 引入了监听器容器工厂来支持`@RabbitListener`并使用`RabbitListenerEndpointRegistry`注册容器,如[程序化端点注册](#async-annotation-driven-registration)中所讨论的那样。 @@ -2743,7 +2743,7 @@ public SimpleMessageListenerContainer factoryCreatedContainerNoListener( | |以这种方式创建的容器是正常的`@Bean`实例,并且不在`RabbitListenerEndpointRegistry`中注册。| |---|------------------------------------------------------------------------------------------------------------------------| -##### [](#async-returns)异步`@RabbitListener`返回类型 +##### 异步`@RabbitListener`返回类型 从版本 2.1 开始,`@RabbitListener`(和`@RabbitHandler`)方法可以用异步返回类型`ListenableFuture`和`Mono`来指定,让回复被异步发送。 @@ -2752,7 +2752,7 @@ public SimpleMessageListenerContainer factoryCreatedContainerNoListener( 从版本 2.2.21、2.3.13、2.4.1 开始,当检测到异步返回类型时,`AcknowledgeMode`将自动设置`MANUAL`。此外,带有致命异常的传入消息将被单独地负面确认,以前任何先前未确认的消息也被负面确认。 -##### [](#threading)线程和异步消费者 +##### 线程和异步消费者 异步消费者涉及许多不同的线程。 @@ -2770,7 +2770,7 @@ public SimpleMessageListenerContainer factoryCreatedContainerNoListener( `RabbitMQ client`使用`ThreadFactory`为低级 I/O 操作创建线程。要修改这个工厂,你需要配置底层的 RabbitMQ`ConnectionFactory`,如[配置底层客户机连接工厂](#connection-factory)中所讨论的那样。 -##### [](#choose-container)选择容器 +##### 选择容器 2.0 版引入了`DirectMessageListenerContainer`。在此之前,只有`SimpleMessageListenerContainer`可用。SMLC 为每个使用者使用一个内部队列和一个专用线程。如果一个容器被配置为监听多个队列,那么将使用同一个使用者线程来处理所有队列。并发性由`concurrentConsumers`和其他属性控制。当消息从 RabbitMQ 客户机到达时,客户机线程通过队列将消息传递给消费者线程。之所以需要这种架构,是因为在 RabbitMQ 客户端的早期版本中,不可能实现多个并发交付。较新版本的客户机具有修订后的线程模型,现在可以支持并发。这允许引入 DMLC,现在在 RabbitMQ 客户端线程上直接调用侦听器。因此,它的架构实际上比 SMLC“更简单”。然而,这种方法有一些局限性,并且 SMLC 的某些功能在 DMLC 中不可用。此外,并发性由`consumersPerQueue`(以及客户库的线程池)控制。`concurrentConsumers`和相关属性在此容器中不可用。 @@ -2792,7 +2792,7 @@ public SimpleMessageListenerContainer factoryCreatedContainerNoListener( 有关将哪些配置属性应用于每个容器的信息,请参见[消息侦听器容器配置](#containerAttributes)。 -##### [](#idle-containers)检测空闲异步消费者 +##### 检测空闲异步消费者 尽管效率很高,但异步用户的一个问题是检测它们何时空闲——如果一段时间内没有消息到达,用户可能希望采取一些措施。 @@ -2834,7 +2834,7 @@ public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory() { 在每种情况下,当容器处于空闲状态时,每分钟都会发布一次事件。 -###### [](#event-consumption)事件消耗 +###### 事件消耗 你可以通过实现`ApplicationListener`来捕获空闲事件——它可以是一个普通的侦听器,也可以是一个窄到只接收这个特定事件的侦听器。还可以使用 Spring Framework4.2 中介绍的`@EventListener`。 @@ -2874,7 +2874,7 @@ public class Listener { | |如果希望使用 IDLE 事件停止 Lister 容器,则不应在调用侦听器的线程上调用`container.stop()`,
这样做总是会导致延迟和不必要的日志消息。,相反,
,你应该将事件传递给一个不同的线程,然后该线程可以停止容器。| |---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#micrometer)监视侦听器性能 +##### 监视侦听器性能 从版本 2.2 开始,如果在类路径上检测到`Micrometer`,并且在应用程序上下文中存在`MeterRegistry`,则侦听器容器将自动为侦听器创建和更新微米计`Timer`s。可以通过将容器属性`micrometerEnabled`设置为`false`来禁用计时器。 @@ -2892,7 +2892,7 @@ public class Listener { 可以使用`micrometerTags`容器属性添加其他标记。 -#### [](#containers-and-broker-named-queues)4.1.7。容器和以代理命名的队列 +#### 4.1.7.容器和以代理命名的队列 虽然使用`AnonymousQueue`实例作为自动删除队列是可取的,但从版本 2.1 开始,你可以使用带有侦听器容器的代理命名队列。下面的示例展示了如何做到这一点: @@ -2922,7 +2922,7 @@ public SimpleMessageListenerContainer container() { | |当一个连接被重置并建立了一个新的连接时,新的队列将获得一个新的名称,
由于在重新启动的容器和重新声明的队列之间存在竞争条件,因此将容器的`missingQueuesFatal`属性设置为`false`非常重要,因为容器最初可能会尝试重新连接到旧队列。| |---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#message-converters)4.1.8。消息转换器 +#### 4.1.8.消息转换器 `AmqpTemplate`还定义了用于发送和接收委托给`MessageConverter`的消息的几种方法。`MessageConverter`为每个方向提供了一个方法:一个用于转换**to**a`Message`,另一个用于转换**来自**a`Message`。请注意,当转换为`Message`时,除了对象之外,还可以提供属性。`object`参数通常对应于消息体。下面的清单显示了`MessageConverter`接口定义: @@ -2968,11 +2968,11 @@ Object receiveAndConvert(String queueName) throws AmqpException; | |在[异步消费者](#async-consumer)中提到的`MessageListenerAdapter`也使用了`MessageConverter`。| |---|------------------------------------------------------------------------------------------------------------------| -##### [](#simple-message-converter)`SimpleMessageConverter` +##### `SimpleMessageConverter` `MessageConverter`策略的默认实现称为`SimpleMessageConverter`。这是`RabbitTemplate`的实例所使用的转换器,如果你没有显式地配置替代选项。它处理基于文本的内容、序列化的 Java 对象和字节数组。 -###### [](#converting-from-a-message)从`Message`转换 +###### 从`Message`转换 如果输入`Message`的内容类型以“text”开头(例如,“text/plain”),则它还会检查 Content-Encoding 属性,以确定将`Message`Body 字节数组转换为 Java`String`时要使用的字符集。如果输入`Message`上没有设置内容编码属性,则默认情况下它使用 UTF-8 字符集。如果需要覆盖该默认设置,可以配置`SimpleMessageConverter`的实例,设置其`defaultCharset`属性,并将其注入`RabbitTemplate`实例。 @@ -2982,17 +2982,17 @@ Object receiveAndConvert(String queueName) throws AmqpException; 有关重要信息,请参见[Java 反序列化](#java-deserialization)。 -###### [](#converting-to-a-message)转换为`Message` +###### 转换为`Message` 当从任意 Java 对象转换为`Message`时,`SimpleMessageConverter`同样处理字节数组、字符串和可序列化实例。它将这些转换为字节(在字节数组的情况下,没有任何可转换的内容),并且相应地 SESContent-Type 属性。如果要转换的`Object`与这些类型之一不匹配,则`Message`正文为空。 -##### [](#serializer-message-converter)`SerializerMessageConverter` +##### `SerializerMessageConverter` 这种转换器类似于`SimpleMessageConverter`,只是它可以配置与其它 Spring 框架`Serializer`和`Deserializer`实现的`application/x-java-serialized-object`转换。 有关重要信息,请参见[Java 反序列化](#java-deserialization)。 -##### [](#json-message-converter)Jackson2jsonmessageconverter +##### Jackson2jsonmessageconverter 本节介绍使用`Jackson2JsonMessageConverter`转换到`Message`和从`Message`转换的情况。它有以下几个部分: @@ -3000,7 +3000,7 @@ Object receiveAndConvert(String queueName) throws AmqpException; * [转换自`Message`](#Jackson2jsonmessageconverter-from-message) -###### [](#Jackson2JsonMessageConverter-to-message)转换为`Message` +###### 转换为`Message` 正如上一节中提到的,通常不建议依赖 Java 序列化。JSON(JavaScript Object Notation,JavaScript Object Notation,JavaScript Object Notation)是一种比较常见的替代方法,它在不同的语言和平台上更灵活、更可移植。转换器可以在任何`RabbitTemplate`实例上配置,以覆盖其对`SimpleMessageConverter`默认值的使用。`Jackson2JsonMessageConverter`使用`com.fasterxml.jackson`2.x 库。下面的示例配置`Jackson2JsonMessageConverter`: @@ -3052,7 +3052,7 @@ public DefaultClassMapper classMapper() { 现在,如果发送系统将头设置为`thing1`,转换器将创建一个`Thing1`对象,依此类推。有关从非 Spring 应用程序转换消息的完整讨论,请参见[Receiving JSON from Non-Spring Applications](#spring-rabbit-json)示例应用程序。 -###### [](#Jackson2JsonMessageConverter-from-message)从`Message`转换 +###### 从`Message`转换 根据发送系统添加到头部的类型信息,将入站消息转换为对象。 @@ -3096,13 +3096,13 @@ public void thing1(Thing1 thing1, o.s.messaging.Message message) {...} | |从版本 1.6.11 开始,`Jackson2JsonMessageConverter`,因此,`DefaultJackson2JavaTypeMapper`(`DefaultClassMapper`)提供`trustedPackages`选项,以克服[序列化小工具](https://pivotal.io/security/cve-2017-4995)漏洞。
默认情况下,对于向后兼容,`Jackson2JsonMessageConverter`信任所有包——也就是说,它使用`*`作为选项。| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -###### [](#jackson-abstract)反序列化抽象类 +###### 反序列化抽象类 在版本 2.2.8 之前,如果`@RabbitListener`的推断类型是抽象类(包括接口),则转换器将返回到头部中查找类型信息,如果存在,则使用该信息;如果不存在,则尝试创建抽象类。当使用自定义反序列化器来处理抽象类的自定义`ObjectMapper`时,但传入的消息具有无效的类型标头,这会导致一个问题。 从版本 2.2.8 开始,默认情况下保留以前的行为。如果你有这样的自定义`ObjectMapper`,并且希望忽略类型头,并且总是使用推断类型进行转换,那么将`alwaysConvertToInferredType`设置为`true`。这是向后兼容性所必需的,并且可以避免尝试转换失败时的开销(使用标准`ObjectMapper`)。 -###### [](#data-projection)使用 Spring 数据投影接口 +###### 使用 Spring 数据投影接口 从版本 2.2 开始,你可以将 JSON 转换为 Spring 数据投影接口,而不是具体的类型。这允许对数据进行非常有选择性的、低耦合的绑定,包括从 JSON 文档中的多个位置查找值。例如,以下接口可以定义为消息有效负载类型: @@ -3129,7 +3129,7 @@ public void projection(SomeSample in) { 当用作`@RabbitListener`方法的参数时,接口类型将作为正常类型自动传递给转换器。 -###### [](#json-complex)从`Message`转换为`RabbitTemplate` +###### 从`Message`转换为`RabbitTemplate` 如前所述,类型信息在消息头中传递,以在从消息转换时协助转换器。这在大多数情况下都行得通。然而,当使用泛型类型时,它只能转换简单的对象和已知的“容器”对象(列表、数组和映射)。从版本 2.0 开始,`Jackson2JsonMessageConverter`实现了`SmartMessageConverter`,这使得它可以与新的`RabbitTemplate`方法一起使用,该方法接受`ParameterizedTypeReference`参数。这允许转换复杂的泛型类型,如下例所示: @@ -3141,7 +3141,7 @@ Thing1> thing1 = | |从版本 2.1 开始,`AbstractJsonMessageConverter`类已被删除。
它不再是`Jackson2JsonMessageConverter`的基类。
它已被`AbstractJackson2MessageConverter`取代。| |---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#marshallingmessageconverter)`MarshallingMessageConverter` +##### `MarshallingMessageConverter` 还有一个选择是`MarshallingMessageConverter`。它委托给 Spring OXM 库的`Marshaller`和`Unmarshaller`策略接口的实现。你可以阅读有关该库的更多信息[here](https://docs.spring.io/spring/docs/current/spring-framework-reference/html/oxm.html)。在配置方面,最常见的是仅提供构造函数参数,因为`Marshaller`的大多数实现也实现`Unmarshaller`。下面的示例展示了如何配置`MarshallingMessageConverter`: @@ -3156,7 +3156,7 @@ Thing1> thing1 =
``` -##### [](#jackson2xml)`Jackson2XmlMessageConverter` +##### `Jackson2XmlMessageConverter` 这个类是在版本 2.1 中引入的,可以用于将消息从 XML 转换为 XML。 @@ -3185,7 +3185,7 @@ Thing1> thing1 = | |从版本 2.2 开始,如果不存在`contentType`属性,或者它具有默认值`application/octet-stream`,则假定`application/xml`。
恢复到以前的行为(返回未转换的`byte[]`),将转换器的`assumeSupportedContentType`属性设置为`false`。| |---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#contenttypedelegatingmessageconverter)`ContentTypeDelegatingMessageConverter` +##### `ContentTypeDelegatingMessageConverter` 这个类是在版本 1.4.2 中引入的,允许基于`MessageProperties`中的 Content type 属性将任务委托给特定的`MessageConverter`。默认情况下,如果没有`contentType`属性,或者有一个值与所有配置的转换器都不匹配,那么它将委托给`SimpleMessageConverter`。下面的示例配置`ContentTypeDelegatingMessageConverter`: @@ -3200,14 +3200,14 @@ Thing1> thing1 =
``` -##### [](#java-deserialization)Java 反序列化 +##### Java 反序列化 本节介绍如何反序列化 Java 对象。 | |当从不受信任的源反序列化 Java 对象时,可能存在一个漏洞,

如果你接受来自不受信任的源的消息,并且`content-type`的值为`application/x-java-serialized-object`,你应该
考虑配置哪些包和类被允许进行反序列化。
这适用于`SimpleMessageConverter`和`SerializerMessageConverter`,当它被配置为隐式或通过配置使用`DefaultDeserializer`时。
默认情况下,允许的列表为空,这意味着所有的类都是反序列化的。

你可以设置一个模式列表,例如`thing1.`**,`thing1.thing2.Cat`或`.MySafeClass`。
在找到匹配之前,将按顺序检查模式。
如果不匹配,则将不匹配,抛出一个`SecurityException`。

可以在这些转换器上使用`allowedListPatterns`属性设置模式。| |---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#message-properties-converters)消息属性转换器 +##### 消息属性转换器 `MessagePropertiesConverter`策略接口用于在兔子客户端`BasicProperties`和 Spring AMQP`MessageProperties`之间进行转换。默认的实现(`DefaultMessagePropertiesConverter`)对于大多数目的来说通常是足够的,但是如果需要,你可以实现自己的实现。当大小不大于`1024`字节时,默认属性转换器将类型`BasicProperties`的元素转换为`String`实例。较大的`LongString`实例未被转换(请参见下一段)。可以使用构造函数参数重写此限制。 @@ -3256,7 +3256,7 @@ public DefaultMessagePropertiesConverter(int longStringLimit, boolean convertLon 从版本 2.2 开始,`DefaultMessagePropertiesConverter`使用`getName()`而不是`toString()`转换类型为`Class`的任何自定义标头;这避免了使用`toString()`表示来解析类名称的应用程序。对于滚动升级,你可能需要更改你的消费者来理解这两种格式,直到所有的生产者都升级了。 -#### [](#post-processing)4.1.9。修改消息-压缩和更多 +#### 4.1.9.修改消息-压缩和更多 存在一些扩展点。它们允许你对消息执行一些处理,可以在消息发送到 RabbitMQ 之前,也可以在收到消息之后立即进行处理。 @@ -3276,7 +3276,7 @@ public DefaultMessagePropertiesConverter(int longStringLimit, boolean convertLon 从版本 2.1.4 开始,`addBeforePublishPostProcessors()`和`addAfterReceivePostProcessors()`已添加到`RabbitTemplate`中,以允许将新的后处理程序分别附加到发布前和接收后处理程序的列表中。还提供了删除后置处理器的方法。类似地,`AbstractMessageListenerContainer`还添加了`addAfterReceivePostProcessors()`和`removeAfterReceivePostProcessor()`方法。有关更多详细信息,请参见`RabbitTemplate`和`AbstractMessageListenerContainer`的 javadoc。 -#### [](#request-reply)4.1.10。请求/回复消息 +#### 4.1.10.请求/回复消息 `AmqpTemplate`还提供了各种`sendAndReceive`方法,这些方法接受前面描述的用于单向发送操作的相同参数选项(`exchange`,`routingKey`和`Message`)。这些方法在请求-回复场景中非常有用,因为它们在发送之前处理必要的`reply-to`属性的配置,并且可以在内部为此目的创建的独占队列中侦听应答消息。 @@ -3288,7 +3288,7 @@ public DefaultMessagePropertiesConverter(int longStringLimit, boolean convertLon 从版本 2.1 开始,你可以使用`noLocalReplyConsumer`选项配置`RabbitTemplate`,以控制用于回复消费者的`noLocal`标志。默认情况下,这是`false`。 -##### [](#reply-timeout)回复超时 +##### 回复超时 默认情况下,发送和接收方法在 5 秒后超时并返回 null。你可以通过设置`replyTimeout`属性来修改此行为。从版本 1.5 开始,如果你将`mandatory`属性设置为`true`(或者对于特定的消息,`mandatory-expression`计算为`true`),如果无法将消息传递到队列,则将抛出`AmqpMessageReturnedException`。此异常具有`returnedMessage`、`replyCode`和`replyText`属性,以及用于发送的`exchange`和`routingKey`属性。 @@ -3299,7 +3299,7 @@ public DefaultMessagePropertiesConverter(int longStringLimit, boolean convertLon 从版本 2.0.11 和 2.1.3 开始,当你使用默认的`DirectReplyToMessageListenerContainer`时,你可以通过设置模板的`replyErrorHandler`属性来添加错误处理程序。对于任何失败的交付,例如在没有相关标头的情况下收到的延迟回复和消息,都会调用此错误处理程序。传入的异常是`ListenerExecutionFailedException`,它具有`failedMessage`属性。 -##### [](#direct-reply-to)RabbitMQ 直接回复-回复 +##### RabbitMQ 直接回复-回复 | |从 3.4.0 版本开始,RabbitMQ 服务器支持[直接回复](https://www.rabbitmq.com/direct-reply-to.html)。
这消除了固定回复队列的主要原因(以避免需要创建临时队列)对于每个请求)。
以 Spring AMQP 版本 1.4.1 开始的直接回复默认情况下使用(如果服务器支持的话),而不是创建临时回复队列。
当没有`replyQueue`被提供时(或者它的名称设置为`amq.rabbitmq.reply-to`),`RabbitTemplate`自动检测是否支持直接回复,并使用它或退回到使用临时回复队列。
当使用直接回复时,不需要`reply-listener`,也不应进行配置。| |---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| @@ -3316,7 +3316,7 @@ public DefaultMessagePropertiesConverter(int longStringLimit, boolean convertLon 从版本 2.3.7 开始,模板有一个新的属性`useChannelForCorrelation`。当这是`true`时,服务器不必将相关 ID 从请求消息头复制到回复消息。相反,用于发送请求的通道用于将答复与请求关联起来。 -##### [](#message-correlation-with-a-reply-queue)与回复队列的消息相关性 +##### 与回复队列的消息相关性 当使用固定的应答队列(`amq.rabbitmq.reply-to`除外)时,必须提供相关数据,以便能够将应答与请求关联起来。见[RabbitMQ 远程过程调用](https://www.rabbitmq.com/tutorials/tutorial-six-java.html)。默认情况下,标准`correlationId`属性用于保存相关数据。但是,如果希望使用自定义属性来保存相关数据,则可以在 \上设置`correlation-key`属性。显式地将属性设置为`correlationId`与省略该属性相同。对于相关数据,客户机和服务器必须使用相同的报头。 @@ -3328,7 +3328,7 @@ public DefaultMessagePropertiesConverter(int longStringLimit, boolean convertLon | |相关 ID 必须是唯一的,以避免对请求返回错误答复的可能性。| |---|---------------------------------------------------------------------------------------------------------| -##### [](#reply-listener)回复侦听器容器 +##### 回复侦听器容器 当使用 3.4.0 之前的 RabbitMQ 版本时,将为每个回复使用一个新的临时队列。但是,可以在模板上配置单个回复队列,这样效率更高,还可以让你在该队列上设置参数。但是,在这种情况下,你还必须提供一个 \子元素。这个元素为应答队列提供了一个侦听器容器,模板就是侦听器。在 \上允许的所有[消息侦听器容器配置](#containerAttributes)属性在元素上都是允许的,但`connection-factory`和`message-converter`除外,它们是从模板的配置中继承而来的。 @@ -3421,7 +3421,7 @@ public DefaultMessagePropertiesConverter(int longStringLimit, boolean convertLon 有关配置死字的更多信息,请参见[RabbitMQ 死信文档](https://www.rabbitmq.com/dlx.html)。你还可以查看`FixedReplyQueueDeadLetterTests`测试用例。 -##### [](#async-template)异步兔子模板 +##### 异步兔子模板 1.6 版引入了`AsyncRabbitTemplate`。它具有与[`AmqpTemplate`](#amqp-template)上的方法类似的`sendAndReceive`(和`convertSendAndReceive`)方法。然而,它们返回的不是阻塞,而是`ListenableFuture`。 @@ -3502,7 +3502,7 @@ public AsyncRabbitTemplate(RabbitTemplate template) 版本 2.0 引入了这些方法的变体(`convertSendAndReceiveAsType`),这些方法接受一个额外的`ParameterizedTypeReference`参数来转换复杂的返回类型。你必须使用`SmartMessageConverter`配置底层`RabbitTemplate`。有关更多信息,请参见[从`Message`转换为`RabbitTemplate`]。 -##### [](#remoting) Spring 带有 AMQP 的远程控制 +##### Spring 带有 AMQP 的远程控制 | |该功能已被弃用,将在 3.0 中删除。
它已被[处理异常](#annotation-error-handling)取代了很长一段时间,`returnExceptions`被设置为 true,并在发送端配置了`RemoteInvocationAwareMessageConverterAdapter`。
有关更多信息,请参见[处理异常](#annotation-error-handling)。| |---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| @@ -3568,7 +3568,7 @@ Spring 框架具有一般的远程处理能力,允许使用各种传输的[远 | |默认情况下,如果无法传递请求消息,则调用线程最终超时,并抛出一个`RemoteProxyFailureException`。
默认情况下,超时为 5 秒。
你可以通过在`RabbitTemplate`上设置`replyTimeout`属性来修改持续时间,
从 1.5 版本开始,通过将`mandatory`属性设置为`true`并在连接工厂上启用返回(参见[发布者确认并返回](#cf-pub-conf-ret)),调用线程抛出一个`AmqpMessageReturnedException`。
查看[回复超时](#reply-timeout)以获取更多信息。| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#broker-configuration)4.1.11。配置代理 +#### 4.1.11.配置代理 AMQP 规范描述了如何使用该协议在代理上配置队列、交换和绑定。在`org.springframework.amqp.core`包中的`AmqpAdmin`接口中存在这些操作(可从 0.8 规范和更高版本移植)。该类的 RabbitMQ 实现`RabbitAdmin`位于`org.springframework.amqp.rabbit.core`包中。 @@ -3724,7 +3724,7 @@ no-arg`declareQueue()`方法在代理上定义了一个具有自动生成的名 此外,任何声明异常都会导致`DeclarationExceptionEvent`的发布,这是一个`ApplicationEvent`,可以由上下文中的任何`ApplicationListener`使用。该事件包含对管理、正在声明的元素和`Throwable`的引用。 -##### [](#headers-exchange)headers exchange +##### headers exchange 从版本 1.3 开始,你可以将`HeadersExchange`配置为在多个头上匹配。你还可以指定是否必须匹配任何或所有标题。下面的示例展示了如何做到这一点: @@ -3829,7 +3829,7 @@ public class RabbitClientConfiguration extends AbstractStockAppRabbitConfigurati 客户机通过`AmqpAdmin`上的`declareQueue()`方法声明另一个队列。它使用一种路由模式将队列绑定到市场数据交换,该路由模式在属性文件中具体化。 -##### [](#builder-api)用于队列和交换的 Builder API +##### 用于队列和交换的 Builder API 版本 1.6 引入了一个方便的 Fluent API,用于在使用 Java 配置时配置`Queue`和`Exchange`对象。下面的示例展示了如何使用它: @@ -3886,7 +3886,7 @@ public DirectExchange ex() { } ``` -##### [](#collection-declaration)声明交换、队列和绑定的集合 +##### 声明交换、队列和绑定的集合 你可以在`Declarable`对象(`Queue`,`Exchange`,和`Binding`)的集合中包装`Declarables`对象。`RabbitAdmin`在应用程序上下文中检测此类 bean(以及离散`Declarable`bean),并在每次建立连接时(最初和连接失败后)在代理上声明所包含的对象。下面的示例展示了如何做到这一点: @@ -3973,7 +3973,7 @@ public SimpleMessageListenerContainer container(ConnectionFactory connectionFact } ``` -##### [](#conditional-declaration)条件声明 +##### 条件声明 默认情况下,所有队列、交换和绑定都由应用程序上下文中的所有`RabbitAdmin`实例声明(假设它们具有`auto-startup="true"`)。 @@ -4046,7 +4046,7 @@ public Binding binding() { } ``` -##### [](#note-id-name)关于`id`和`name`属性的注释 +##### 关于`id`和`name`属性的注释 ``和``元素上的`name`属性反映了代理中实体的名称。对于队列,如果省略`name`,则创建一个匿名队列(参见[`AnonymousQueue`](#anonymous-queue))。 @@ -4062,7 +4062,7 @@ public Binding binding() { 如果元素仅具有`name`属性,则不会发生更改。 Bean 仍然可以被`name`引用——例如,在绑定声明中。但是,如果名称包含 SPEL,则仍然不能引用它——你必须提供`id`以供引用。 -##### [](#anonymous-queue)`AnonymousQueue` +##### `AnonymousQueue` 通常,当你需要一个唯一命名的、排他的、自动删除的队列时,我们建议你使用`AnonymousQueue`而不是代理定义的队列名称(使用`""`作为`Queue`名称,使代理生成队列名称)。 @@ -4123,7 +4123,7 @@ Base64 编码使用了 RFC4648 中的“URL 和文件名安全字母表”。删 从版本 2.1 开始,默认情况下,匿名队列的声明参数`Queue.X_QUEUE_LEADER_LOCATOR`设置为`client-local`。这确保了队列是在应用程序连接的节点上声明的。在构造实例之后,你可以通过调用`queue.setLeaderLocator(null)`来恢复到以前的行为。 -##### [](#declarable-recovery)恢复自动删除声明 +##### 恢复自动删除声明 通常,`RabbitAdmin`(s)只恢复在应用程序上下文中声明为 bean 的队列/交换/绑定;如果任何此类声明是自动删除的,则如果连接丢失,代理将删除它们。当重新建立连接时,管理员将重新声明这些实体。通常,通过调用`admin.declareQueue(…​)`、`admin.declareExchange(…​)`和`admin.declareBinding(…​)`创建的实体将不会被恢复。 @@ -4133,7 +4133,7 @@ Base64 编码使用了 RFC4648 中的“URL 和文件名安全字母表”。删 最后,调用`resetAllManualDeclarations()`将阻止恢复任何先前声明的实体。 -#### [](#broker-events)4.1.12。代理事件监听器 +#### 4.1.12.代理事件监听器 当启用[事件交换插件 Name](https://www.rabbitmq.com/event-exchange.html)时,如果将类型`BrokerEventListener`的 Bean 添加到应用程序上下文中,则它将所选的代理事件发布为`BrokerEvent`实例,该实例可以通过正常的 Spring `ApplicationListener`或`@EventListener`方法来使用。事件由代理发布到主题交换`amq.rabbitmq.event`,每个事件类型都有不同的路由密钥。侦听器使用事件键,用于将`AnonymousQueue`绑定到交换,以便侦听器仅接收选定的事件。由于这是一个主题交换,所以可以使用通配符(以及显式地请求特定事件),如下例所示: @@ -4153,7 +4153,7 @@ public void listener(BrokerEvent event) { } ``` -#### [](#delayed-message-exchange)4.1.13。延迟的消息交换 +#### 4.1.13.延迟的消息交换 版本 1.6 引入了对[延迟消息交换插件 Name](https://www.rabbitmq.com/blog/2015/04/16/scheduling-messages-with-rabbitmq/)的支持 @@ -4191,7 +4191,7 @@ rabbitTemplate.convertAndSend(exchange, routingKey, "foo", new MessagePostProces 要检查消息是否延迟,请在`MessageProperties`上使用`getReceivedDelay()`方法。它是一个单独的属性,以避免意外传播到由输入消息生成的输出消息。 -#### [](#management-rest-api)4.1.14。RabbitMQ REST API +#### 4.1.14.RabbitMQ REST API 启用管理插件后,RabbitMQ 服务器公开一个 REST API 来监视和配置代理。a[API 的 Java 绑定](https://github.com/rabbitmq/hop)现已提供。`com.rabbitmq.http.client.Client`是一个标准的、直接的 API,因此是阻塞的 API。它是基于[Spring Web](https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#spring-web)模块及其`RestTemplate`实现的。另一方面,`com.rabbitmq.http.client.ReactorNettyClient`是一个基于[反应堆网状结构](https://projectreactor.io/docs/netty/release/reference/docs/index.html)项目的反应式、非阻塞实现。 @@ -4199,7 +4199,7 @@ rabbitTemplate.convertAndSend(exchange, routingKey, "foo", new MessagePostProces 有关更多信息,请访问他们的 Javadoc。 -#### [](#exception-handling)4.1.15。异常处理 +#### 4.1.15.异常处理 使用 RabbitMQ Java 客户机的许多操作都可以抛出检查过的异常。例如,在很多情况下`IOException`实例可能会被抛出。`RabbitTemplate`、`SimpleMessageListenerContainer`和其他 Spring AMQP 组件捕获这些异常,并将它们转换为`AmqpException`层次结构中的一个异常。这些在’org.springframework.amqp’包中定义,而`AmqpException`是层次结构的基础。 @@ -4230,7 +4230,7 @@ rabbitTemplate.convertAndSend(exchange, routingKey, "foo", new MessagePostProces | |从版本 2.1.9 开始,具有这些致命异常的消息将被拒绝,并且默认情况下不会重新请求,即使容器确认模式是手动的。
这些异常通常发生在调用侦听器之前,因此侦听器没有机会对消息进行 ACK 或 NACK,因此消息仍处于未 ACKED 状态。
以恢复到先前的行为,将`ConditionalRejectingErrorHandler`上的`rejectManual`属性设置为`false`。| |---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#transactions)4.1.16。交易 +#### 4.1.16.交易 Spring Rabbit Framework 具有对同步和异步用例中的自动事务管理的支持,其具有许多不同的语义,这些语义可以通过声明方式进行选择,这是 Spring 事务的现有用户所熟悉的。这使得许多即使不是最常见的消息传递模式也很容易实现。 @@ -4274,7 +4274,7 @@ public class ExampleExternalTransactionAmqpConfiguration { 在前面的示例中,事务管理器被添加为从另一个 Bean 定义注入的依赖项(未示出),并且`channelTransacted`标志也被设置为`true`。其结果是,如果侦听器发生异常而失败,事务将被回滚,消息也将返回给代理。值得注意的是,如果事务未能提交(例如,由于数据库约束错误或连接问题),AMQP 事务也将回滚,并将消息返回给代理。这有时被称为“尽最大努力 1 阶段提交”,是可靠消息传递的一个非常强大的模式。如果在前面的示例中将`channelTransacted`标志设置为`false`(默认值),则仍将为侦听器提供外部事务,但是所有消息传递操作都将被自动 ACK,因此其效果是即使在业务操作的回滚时也提交消息传递操作。 -##### [](#conditional-rollback)条件回滚 +##### 条件回滚 在 1.6.6 版本之前,在使用外部事务管理器(例如 JDBC)时,向容器的`transactionAttribute`添加回滚规则不会产生任何效果。异常总是回滚事务。 @@ -4298,7 +4298,7 @@ public AbstractMessageListenerContainer container() { } ``` -##### [](#transaction-rollback)关于回滚接收消息的说明 +##### 关于回滚接收消息的说明 AMQP 事务只适用于发送给代理的消息和 ACK。因此,当对 Spring 事务进行回滚并且已经接收到消息时, Spring AMQP 不仅必须回滚该事务,而且还必须手动拒绝该消息(有点像 nack,但这不是规范所称的那样)。对消息拒绝所采取的操作独立于事务,并且依赖于`defaultRequeueRejected`属性(默认值:`true`)。有关拒绝失败消息的更多信息,请参见[消息侦听器和异步情况](#async-listeners)。 @@ -4310,7 +4310,7 @@ AMQP 事务只适用于发送给代理的消息和 ACK。因此,当对 Spring | |以前,在本地事务回滚和提供`TransactionManager`时,对事务回滚的消息请求是不一致的。
在前一种情况下,应用正常的请求逻辑(`AmqpRejectAndDontRequeueException`或`defaultRequeueRejected=false`)(参见[消息侦听器和异步情况](#async-listeners))。
与事务管理器,从版本 2.0 开始,该行为是一致的,并且在这两种情况下都应用了正常的请求逻辑。
要恢复到以前的行为,你可以将容器的`alwaysRequeueWithTxManagerRollback`属性设置为`true`。
参见[消息侦听器容器配置](#containerAttributes)。| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#using-rabbittransactionmanager)使用`RabbitTransactionManager` +##### 使用`RabbitTransactionManager` [RabbitTransactionManager](https://docs.spring.io/spring-amqp/docs/latest_ga/api/org/springframework/amqp/rabbit/transaction/RabbitTransactionManager.html)是在外部事务中执行 Rabbit 操作并与之同步的一种替代方法。此事务管理器是[`PlatformTransactionManager`](https://DOCS. Spring.io/ Spring/DOCS/current/javadoc-api/org/springframework/transactionmanager.html)接口的实现,应该与单个 Rabbit`ConnectionFactory`一起使用。 @@ -4337,13 +4337,13 @@ public RabbitTransactionManager rabbitTransactionManager() { ``` -##### [](#tx-sync)事务同步 +##### 事务同步 将 RabbitMQ 事务与其他事务(例如 DBMS)同步提供了“Best Effort One Phase Commit”语义。在事务同步的完成后阶段,RabbitMQ 事务可能无法提交。这是由`spring-tx`基础架构作为错误记录的,但不会向调用代码抛出异常。从版本 2.3.10 开始,你可以在事务在处理该事务的同一线程上提交后调用`ConnectionUtils.checkAfterCompletion()`。如果没有发生异常,它将简单地返回;否则它将抛出一个`AfterCompletionFailedException`,该属性将具有表示完成的同步状态的属性。 通过调用`ConnectionFactoryUtils.enableAfterCompletionFailureCapture(true)`来启用此功能;这是一个全局标志,适用于所有线程。 -#### [](#containerAttributes)4.1.17。消息侦听器容器配置 +#### 4.1.17.消息侦听器容器配置 对于配置与事务和服务质量相关的`SimpleMessageListenerContainer`和`DirectMessageListenerContainer`有相当多的选项,其中一些选项相互交互。适用于 SMLC、DMLC 或`StreamListenerContainer`(见[使用 RabbitMQ 流插件](#stream-support))的属性由相应列中的复选标记指示。有关帮助你决定哪个容器适合你的应用程序的信息,请参见[选择容器](#choose-container)。 @@ -4351,71 +4351,71 @@ public RabbitTransactionManager rabbitTransactionManager() { | Property
(Attribute) |说明| SMLC | DMLC | StLC | |-----------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------|--------------------------------|--------------------------------| -| []()[`ackTimeout`](#ackTimeout)
(N/A) |当`messagesPerAck`被设置时,这个超时被用作发送 ACK 的替代方法。
当一个新的消息到达时,未加 ACK 的消息的计数与`messagesPerAck`进行比较,并且将自上次 ACK 的时间与该值进行比较。
如果任一条件是`true`,当没有新的消息到达并且有未加锁的消息时,这个超时是近似的,因为每个条件只检查`monitorInterval`。
在这个表中还可以看到`messagesPerAck`和`monitorInterval`。| |![tickmark](images/tickmark.png)| | -| []()[`acknowledgeMode`](#acknowledgeMode)
(acknowledge) |*`NONE`:未发送 ACK(与`channelTransacted=true`不兼容),
RabbitMQ 将此称为“自动 ACK”,因为代理假定所有消息都是 ACK 的,而不需要消费者的任何操作。

*`MANUAL`:侦听器必须通过调用`Channel.basicAck()`来确认所有消息。

*`AUTO`:容器自动确认消息,除非`MessageListener`抛出异常。
注意,`acknowledgeMode`与`channelTransacted`是互补的——如果通道被处理,代理除了 ACK 之外还需要一个提交通知。
这是默认模式。
参见`batchSize`。|![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | -| []()[`adviceChain`](#adviceChain)
(advice-chain) |将 AOP 通知的数组应用到侦听器执行。
这可以用于应用额外的横切关注点,例如在代理死亡的情况下自动重试。
注意,在 AMQP 错误之后的简单重新连接由`CachingConnectionFactory`处理,只要经纪人还活着。|![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | -| []()[`afterReceivePostProcessors`](#afterReceivePostProcessors)
(N/A) |在调用侦听器之前调用的`MessagePostProcessor`实例的数组。
POST 处理器可以实现`PriorityOrdered`或`Ordered`。
该数组与上次调用的未排序成员进行排序。
如果 POST 处理器返回`null`,则该消息将被丢弃(并在适当的情况下得到确认)。|![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | -| []()[`alwaysRequeueWithTxManagerRollback`](#alwaysRequeueWithTxManagerRollback)
(N/A) |设置为`true`,以便在配置事务管理器时始终请求回滚消息。|![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | -| []()[`autoDeclare`](#autoDeclare)
(auto-declare) |当设置为`true`(默认)时,容器使用`RabbitAdmin`来重新声明所有 AMQP 对象(队列、交换、绑定),如果它在启动过程中检测到至少有一个队列丢失,可能是因为它是`auto-delete`或过期的队列,但是如果队列由于任何原因丢失,则重新声明继续进行。
要禁用此行为,将此属性设置为`false`。
注意,如果缺少所有队列,则容器将无法启动。

| |Prior to version 1.6, if there was more than one admin in the context, the container would randomly select one.
If there were no admins, it would create one internally.
In either case, this could cause unexpected results.
Starting with version 1.6, for `autoDeclare` to work, there must be exactly one `RabbitAdmin` in the context, or a reference to a specific instance must be configured on the container using the `rabbitAdmin` property.|
|---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | +| | | +| | | +| | | +| | | +| | | +| | | | |在版本 1.6 之前,如果上下文中有一个以上的管理员,容器将随机选择一个。
如果没有管理员,它将在内部创建一个。
在这两种情况下,这都可能导致意外的结果。
从版本 1.6 开始,对于`autoDeclare`来说,上下文中必须正好有一个`RabbitAdmin`,或者必须使用`rabbitAdmin`属性在容器上配置对特定实例的引用。| | | | -| []()[`autoStartup`](#autoStartup)
(auto-startup) |表示容器应该在`ApplicationContext`开始时启动(作为`SmartLifecycle`回调的一部分,回调发生在初始化所有 bean 之后),
默认为`true`,但是,如果你的代理在启动时可能不可用,你可以将其设置为`false`,并在知道代理已经准备好时,稍后手动调用`start()`。|![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| -| []()[`batchSize`](#batchSize)
(transaction-size)
(batch-size) |当与`acknowledgeMode`一起使用时,将其设置为`AUTO`,容器在发送 ACK 之前尝试处理多达这个数量的消息(等待每个消息到接收超时设置),
这也是提交事务通道时的情况,
如果`prefetchCount`小于`batchSize`,它被增加以匹配`batchSize`。|![tickmark](images/tickmark.png)| | | -| []()[`batchingStrategy`](#batchingStrategy)
(N/A) |删除消息时使用的策略。
默认`SimpleDebatchingStrategy`。
参见[Batching](#template-batching)和[@RabbitListener 与批处理](#receiving-batch)。|![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | -| []()[`channelTransacted`](#channelTransacted)
(channel-transacted) |布尔标志表示所有消息都应该在事务中得到确认(手动或自动)。|![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | -| []()[`concurrency`](#concurrency)
(N/A) |`m-n`每个侦听器的并发消费者的范围。
如果只提供`n`,`n`是固定数量的消费者。
参见[监听器并发](#listener-concurrency)。|![tickmark](images/tickmark.png)| | | -| []()[`concurrentConsumers`](#concurrentConsumers)
(concurrency) |每个侦听器最初要启动的并发消费者的数量。
参见[监听器并发](#listener-concurrency)。|![tickmark](images/tickmark.png)| | | -| []()[`connectionFactory`](#connectionFactory)
(connection-factory) |对`ConnectionFactory`的引用。
在配置 byusing XML 名称空间时,默认引用的 Bean 名称是`rabbitConnectionFactory`。|![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | -| []()[`consecutiveActiveTrigger`](#consecutiveActiveTrigger)
(min-consecutive-active) |当考虑启动一个新的使用者时,一个使用者在不发生接收超时的情况下接收的连续消息的最小数量。
也受到“batchsize”的影响。
参见[监听器并发](#listener-concurrency)。
默认值:10。|![tickmark](images/tickmark.png)| | | -| []()[`consecutiveIdleTrigger`](#consecutiveIdleTrigger)
(min-consecutive-idle) |消费者在考虑停止一个消费者之前必须经历的接收超时的最小数量。
也受到“batchsize”的影响。
参见[监听器并发](#listener-concurrency)。
默认值:10。|![tickmark](images/tickmark.png)| | | -| []()[`consumerBatchEnabled`](#consumerBatchEnabled)
(batch-enabled) |如果`MessageListener`支持它,将其设置为 true 可以对离散消息进行批处理,最多`batchSize`;如果`receiveTimeout`中没有新消息到达,则将交付部分批处理。
如果这是 false,则仅支持由生产者创建的批处理;请参见[Batching](#template-batching)。|![tickmark](images/tickmark.png)| | | -| []()[`consumerCustomizer`](#consumerCustomizer)
(N/A) |用于修改由容器创建的流消费者的`ConsumerCustomizer` Bean。| | |![tickmark](images/tickmark.png)| -| []()[`consumerStartTimeout`](#consumerStartTimeout)
(N/A) |等待消费线程启动的时间(以毫秒为单位)。
如果这段时间过了,如果配置的`taskExecutor`没有足够的线程来支持容器`concurrentConsumers`。

可能发生这种情况的一个例子是,
默认情况:60000(一分钟)。|![tickmark](images/tickmark.png)| | | -| []()[`consumerTagStrategy`](#consumerTagStrategy)
(consumer-tag-strategy) |设置[消费者策略](#consumerTags)的实现,以便为每个消费者创建一个(唯一的)标记。|![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | -| []()[`consumersPerQueue`](#consumersPerQueue)
(consumers-per-queue) |为每个配置好的队列创建的消费者的数量。
参见[监听器并发](#listener-concurrency)。| |![tickmark](images/tickmark.png)| | -| []()[`consumeDelay`](#consumeDelay)
(N/A) |当使用[RabbitMQ 分片插件](https://github.com/rabbitmq/rabbitmq-sharding)与`concurrentConsumers > 1`时,存在一种竞争条件,可以防止消费者在碎片之间的均匀分布。
使用此属性在消费者开始之间添加一个小的延迟,以避免这种竞争条件。
你应该对值进行实验,以确定适合你的环境的延迟。|![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | -| []()[`debatchingEnabled`](#debatchingEnabled)
(N/A) |当为真时,侦听器容器将删除批处理的消息,并用批处理中的每条消息调用侦听器。,
从 2.2.7 版本开始,如果侦听器是`BatchMessageListener`或`ChannelAwareBatchMessageListener`,则[生产者创建了批](#template-batching)将被取消为[生产者创建了批](#template-batching)。否则,批处理中的消息将一次显示一次。
默认为真。
参见[Batching](#template-batching)和[@RabbitListener 与批处理](#receiving-batch)。|![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | -| []()[`declarationRetries`](#declarationRetries)
(declaration-retries) |被动队列声明失败时重试尝试的次数。
被动队列声明发生在使用者启动或从多个队列消费时,当初始化期间不是所有的队列都可用时。
当重试用完后不能被动地声明(出于任何原因)配置的队列时,容器行为由前面描述的“missingqueuesfatal”属性控制。
默认情况:三次重试(总共四次尝试)。|![tickmark](images/tickmark.png)| | | -| []()[`defaultRequeueRejected`](#defaultRequeueRejected)
(requeue-rejected) |确定是否应重新请求因侦听器抛出异常而被拒绝的消息。
默认:`true`。|![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | -| []()[`errorHandler`](#errorHandler)
(error-handler) |对`ErrorHandler`策略的引用,该策略用于处理在执行 MessageListener 期间可能发生的任何未捕获的异常。
默认:`ConditionalRejectingErrorHandler`|![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | -| []()[`exclusive`](#exclusive)
(exclusive) |确定此容器中的单个使用者是否对队列具有独占访问权限。
当这是`true`时,容器的并发性必须为 1,
如果另一个使用者具有独占访问权限,则容器将尝试恢复该使用者,根据`recovery-interval`或`recovery-back-off`.
使用名称空间时,该属性将与队列名称一起出现在``元素上。
默认:`false`。|![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | -| []()[`exclusiveConsumerExceptionLogger`](#exclusiveConsumerExceptionLogger)
(N/A) |当独占使用者无法访问队列时使用的异常记录器。
默认情况下,这是在`WARN`级别上记录的。|![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | -| []()[`failedDeclarationRetryInterval`](#failedDeclarationRetryInterval)
(failed-declaration
-retry-interval) |被动队列声明重试尝试之间的间隔。
被动队列声明发生在使用者启动时,或者在从多个队列消费时,当初始化期间不是所有队列都可用时。
默认值:5000(5 秒)。|![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | -| []()[`forceCloseChannel`](#forceCloseChannel)
(N/A) |如果消费者在`shutdownTimeout`内没有对关机做出响应,如果这是`true`,则通道将被关闭,从而导致任何未被 ACKed 的消息被重新请求。
自 2.0 起默认为`true`。
你可以将其设置为`false`以恢复到以前的行为。|![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | -| []()[`globalQos`](#globalQos)
(global-qos) |当为真时,`prefetchCount`将全局地应用于通道,而不是应用于通道上的每个消费者。
有关更多信息,请参见[`basicQos.global`](https://WWW.rabbitmq.com/amqp-0-9-1-reference.html#basic.qos.global)。|![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | +| | +| | | | +| | | +| | | +| | | | +| | | | +| | | +| | | | +| | | | +| | | | +| | +| | | | +| | | +| | | +| | | +| | | +| | | | +| | | +| | | +| | | +| | | +| | | +| | | +| | | | (group) |这仅在使用名称空间时可用。
当指定时,类型`Collection`的 Bean 被注册为该名称,并且每个
元素的
容器被添加到集合中。
例如,这允许,通过迭代集合来启动和停止容器组。
如果多个``元素具有相同的组值,集合形式中的容器
是如此指定的所有容器的集合。|![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | -| []()[`idleEventInterval`](#idleEventInterval)
(idle-event-interval) |见[检测空闲异步消费者](#idle-containers)。|![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | -| []()[`javaLangErrorHandler`](#javaLangErrorHandler)
(N/A) |当容器线程捕获`Error`时调用的`AbstractMessageListenerContainer.JavaLangErrorHandler`实现。
默认实现调用`System.exit(99)`;要恢复到以前的行为(什么都不做),请添加一个 no-op 处理程序。|![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | -| []()[`maxConcurrentConsumers`](#maxConcurrentConsumers)
(max-concurrency) |如果需要,按需启动的最大并发消费者数量。
必须大于或等于“concurrentConsumers”。
参见[监听器并发](#listener-concurrency)。|![tickmark](images/tickmark.png)| | | -| []()[`messagesPerAck`](#messagesPerAck)
(N/A) |ACK 之间要接收的消息的数量。使用此方法可以减少发送给代理的 ACK 的数量(以增加重新交付消息的可能性为代价)。通常,你应该仅在大容量的侦听器容器上设置此属性。
如果设置了此属性,并且拒绝了一条消息(抛出了异常),则确认了挂起的 ACK,并且拒绝了失败的消息。
不允许使用已处理的通道。
如果`prefetchCount`小于`messagesPerAck`,它被增加以匹配`messagesPerAck`。
默认值:ACK 每条消息。
参见`ackTimeout`在此表中。| |![tickmark](images/tickmark.png)| | -| []()[`mismatchedQueuesFatal`](#mismatchedQueuesFatal)
(mismatched-queues-fatal) |当容器启动时,如果此属性是`true`(默认值:`false`),则容器将检查上下文中声明的所有队列是否与代理上已经存在的队列兼容。
如果存在不匹配的属性(例如`auto-delete`)或参数(skuch 为`x-message-ttl`),容器(和应用程序上下文)无法以致命的异常启动。

如果在恢复过程中检测到问题(例如,在丢失连接之后),容器被停止。

在应用程序上下文中必须有一个`RabbitAdmin`(或通过使用`rabbitAdmin`属性在容器上专门配置的一个)。
否则,该属性必须是`false`。

| |If the broker is not available during initial startup, the container starts and the conditions are checked when the connection is established.|
|---|----------------------------------------------------------------------------------------------------------------------------------------------|

| |The check is done against all queues in the context, not just the queues that a particular listener is configured to use.
If you wish to limit the checks to just those queues used by a container, you should configure a separate `RabbitAdmin` for the container, and provide a reference to it using the `rabbitAdmin` property.
See [Conditional Declaration](#conditional-declaration) for more information.|
|---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

| |Mismatched queue argument detection is disabled while starting a container for a `@RabbitListener` in a bean that is marked `@Lazy`.
This is to avoid a potential deadlock which can delay the start of such containers for up to 60 seconds.
Applications using lazy listener beans should check the queue arguments before getting a reference to the lazy bean.|
|---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------||![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | +| | | +| | | +| | | | +| | | +| | | | |如果在初始启动期间代理不可用,则容器将启动,并在建立连接时检查条件。| | | | | |检查是针对上下文中的所有队列进行的,而不仅仅是特定侦听器被配置使用的队列,
如果你希望将检查仅限于容器使用的那些队列,那么你应该为容器配置一个单独的`RabbitAdmin`,并使用`rabbitAdmin`属性提供对它的引用。
有关更多信息,请参见[有条件声明](#conditional-declaration)。| | | | | |在 Bean 中为`@RabbitListener`启动容器时,禁用不匹配的队列参数检测这被标记为`@Lazy`。
这是为了避免潜在的死锁,这可能会将此类容器的启动延迟长达 60 秒。
使用 lazy Listener bean 的应用程序应该在获得对 lazy 的引用之前检查队列参数 Bean。| | | | -| []()[`missingQueuesFatal`](#missingQueuesFatal)
(missing-queues-fatal) |当设置为`true`(默认)时,如果代理上没有可用的配置队列,则认为这是致命的,
这会导致应用程序上下文在启动期间无法初始化,
同样,在默认情况下,当容器运行时删除队列时,消费者进行三次重试以连接到队列(每隔五秒),并在尝试失败时停止容器。

这在以前的版本中是不可配置的。

当设置为`false`时,在进行三次重试之后,容器进入恢复模式,与其他问题一样,例如代理被关闭。
容器尝试根据`recoveryInterval`属性进行恢复。
在每次尝试恢复期间,每个使用者再次尝试四次,以五秒的间隔被动地声明队列。
此过程将无限期地继续。

你还可以使用一个属性 Bean 来为所有容器全局地设置属性,如下:

```
id="spring.amqp.global.properties">

false


```

此全局属性不应用于具有显式`missingQueuesFatal`属性集的任何容器。

默认的重试属性(五秒间隔三次重试)可以通过设置下面的属性被重写。
| |Missing queue detection is disabled while starting a container for a `@RabbitListener` in a bean that is marked `@Lazy`.
This is to avoid a potential deadlock which can delay the start of such containers for up to 60 seconds.
Applications using lazy listener beans should check the queue(s) before getting a reference to the lazy bean.|
|---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | +| | | | |在 Bean 中为`@RabbitListener`启动容器时,将禁用丢失的队列检测这被标记为`@Lazy`。
这是为了避免潜在的死锁,这可能会将此类容器的启动延迟长达 60 秒。
使用 Lazy Listener Bean 的应用程序应该在获得对 Lazy 的引用之前检查队列 Bean。| | | | -| []()[`monitorInterval`](#monitorInterval)
(monitor-interval) |对于 DMLC,计划在此间隔时间运行一个任务,以监视使用者的状态并恢复任何失败的任务。| |![tickmark](images/tickmark.png)| | -| []()[`noLocal`](#noLocal)
(N/A) |设置为`true`,以禁用在同一通道的连接上发布的从服务器到消费者的消息传递。|![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | -| []()[`phase`](#phase)
(phase) |当`autoStartup`是`true`时,此容器应在其中开始和停止的生命周期阶段。
值越低,此容器开始的时间越早,停止的时间越晚。
默认值是`Integer.MAX_VALUE`,这意味着容器开始得越晚,停止得越快。|![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | -|[]()[`possibleAuthenticationFailureFatal`](#possibleAuthenticationFailureFatal)
(possible-authentication-failure-fatal)|当设置为`true`(SMLC 的默认值)时,如果在连接过程中抛出了`PossibleAuthenticationFailureException`,它被认为是致命的。
这会导致应用程序上下文在启动期间无法初始化(如果容器配置为自动启动)。

自*2.0 版本*

**directmessageListenerContainer****

(默认),当设置为`false`时,每个使用者将尝试根据`monitorInterval`重新连接。

**SimpleMessageListenerContainer**

当设置为`false`时,在进行 3 次重试之后,容器将进入恢复模式,与其他问题一样,例如代理正在关闭。
容器将根据`recoveryInterval`属性尝试恢复。
在每次尝试恢复期间,每个使用者将再次尝试 4 次以启动。
此过程将无限期地继续。

你还可以使用一个属性 Bean 来全局设置所有容器的属性,如下所示:

```
id="spring.amqp.global.properties">
key="mlc.possible.authentication.failure.fatal">
false


```
此全局属性将不会应用于任何具有显式`missingQueuesFatal`属性集的容器。
默认的重试属性(5 秒间隔 3 次重试)可以在此属性之后使用属性重写。|![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | -| []()[`prefetchCount`](#prefetchCount)
(prefetch) |在每个消费者处可能未完成的未确认消息的数量。
该值越高,消息可以交付得越快,但非顺序处理的风险越高。
如果`acknowledgeMode`是`NONE`,则忽略不计。
如果有必要,要匹配`batchSize`或`messagePerAck`。
自 2.0 起默认值为 250。
你可以将其设置为 1 以恢复到以前的行为。

| |There are scenarios where the prefetch value should
be low — for example, with large messages, especially if the processing is slow (messages could add up
to a large amount of memory in the client process), and if strict message ordering is necessary
(the prefetch value should be set back to 1 in this case).
Also, with low-volume messaging and multiple consumers (including concurrency within a single listener container instance), you may wish to reduce the prefetch to get a more even distribution of messages across consumers.|
|---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

Also see `globalQos`. |![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | +| | | +| | | +| | | +|| | +| | | | |在某些情况下,预取取值应该
较低,例如,对于较大的消息,尤其是在处理速度较慢的情况下(消息可能会将
累加到客户端进程中的大量内存中),如果需要严格的消息排序
(在这种情况下,预取值应该设置为 1),
还可以使用低容量消息传递和多个消费者(包括单个侦听器容器实例中的并发性),你可能希望减少预取,以使消息在消费者之间的分布更加均匀。| | | | -| []()[`rabbitAdmin`](#rabbitAdmin)
(admin) |当侦听器容器侦听至少一个自动删除队列时,发现该队列在启动过程中丢失,则该容器使用`RabbitAdmin`声明队列以及任何相关的绑定和交换,
如果这些元素被配置为使用条件声明(参见[有条件声明](#conditional-declaration)),容器必须使用配置来声明这些元素的管理。
在这里指定该管理。
只有在使用带有条件声明的自动删除队列时才需要。
如果你不希望在容器启动之前声明自动删除队列,在管理员上将`auto-startup`设置为`false`。
默认设置为一个`RabbitAdmin`,该命令声明所有无条件元素。|![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | -| []()[`receiveTimeout`](#receiveTimeout)
(receive-timeout) |等待每条消息的最长时间。
如果`acknowledgeMode=NONE`,这几乎没有影响——容器旋转并请求另一条消息,
对于带有`Channel`的事务性`batchSize > 1`,它的影响最大,因为它可能导致在超时到期之前不确认已经使用的消息。
当`consumerBatchEnabled`为真时,如果在批处理完成之前发生超时,则将交付部分批处理。|![tickmark](images/tickmark.png)| | | -| []()[`recoveryBackOff`](#recoveryBackOff)
(recovery-back-off) |指定`BackOff`如果使用者由于非致命原因而无法启动,则尝试启动使用者之间的间隔。
默认值为`FixedBackOff`,每五秒进行无限次重试。
与`recoveryInterval`互斥。|![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | -| []()[`recoveryInterval`](#recoveryInterval)
(recovery-interval) |如果使用者由于非致命原因而无法启动,则确定尝试启动使用者之间的时间(以毫秒为单位)。
默认值:5000。
与`recoveryBackOff`互斥。|![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | -| []()[`retryDeclarationInterval`](#retryDeclarationInterval)
(missing-queue-
retry-interval) |如果在使用者初始化期间,配置队列的一个子集可用,则使用者开始从这些队列消费。
使用者试图通过使用此间隔被动地声明丢失的队列。
当此间隔过后,将再次使用“declarnationRetries”和“faileddeclarationRetrygt Interval”。,如果仍然存在丢失的队列,
,消费者在再次尝试之前再次等待这个间隔。
此过程将无限期地继续,直到所有队列都可用。
默认值:60000(一分钟)。|![tickmark](images/tickmark.png)| | | -| []()[`shutdownTimeout`](#shutdownTimeout)
(N/A) |当容器关闭时(例如,
如果其封闭的`ApplicationContext`已关闭),它将等待飞行中的消息被处理到这个限制。
默认为 5 秒。|![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | -| []()[`startConsumerMinInterval`](#startConsumerMinInterval)
(min-start-interval) |在按需启动每个新用户之前必须经过的毫秒时间。
参见[监听器并发](#listener-concurrency)。
默认值:10000(10 秒)。|![tickmark](images/tickmark.png)| | | -| []()[`statefulRetryFatal`](#statefulRetryFatal)
WithNullMessageId
(N/A) |当使用有状态重试建议时,如果接收到缺少`messageId`属性的消息,则默认情况下认为
对消费者是致命的(它被停止)。
将此设置为`false`以丢弃(或路由到死信队列)此类消息。|![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | -| []()[`stopConsumerMinInterval`](#stopConsumerMinInterval)
(min-stop-interval) |当检测到空闲消费者时,从最后一个消费者停止到消费者停止之前必须经过的毫秒时间。
参见[监听器并发](#listener-concurrency)。
默认值:60000(一分钟)。|![tickmark](images/tickmark.png)| | | -| []()[`streamConverter`](#streamConverter)
(N/A) |将本机流消息转换为 Spring AMQP 消息的`StreamMessageConverter`。| | |![tickmark](images/tickmark.png)| -| []()[`taskExecutor`](#taskExecutor)
(task-executor) |对用于执行侦听器调用程序的 Spring `TaskExecutor`(或标准 JDK1.5+`Executor`)的引用。
默认值是`SimpleAsyncTaskExecutor`,使用内部管理线程。|![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | -| []()[`taskScheduler`](#taskScheduler)
(task-scheduler) |在 DMLC 中,调度程序用来在“monitorinterval”运行监视任务。| |![tickmark](images/tickmark.png)| | -| []()[`transactionManager`](#transactionManager)
(transaction-manager) |外部事务管理器用于侦听器的操作。
还补充了`channelTransacted`—如果`Channel`被处理,则其事务与外部事务同步。|![tickmark](images/tickmark.png)|![tickmark](images/tickmark.png)| | - -#### [](#listener-concurrency)4.1.18。监听器并发 - -##### [](#simplemessagelistenercontainer)SimpleMessageListenerContainer +| | | +| | | | +| | | +| | | +| | | | +| | | +| | | | +| | | +| | | | +| | +| | | +| | | +| | | + +#### 4.1.18.监听器并发 + +##### SimpleMessageListenerContainer 默认情况下,侦听器容器启动一个从队列接收消息的使用者。 @@ -4440,19 +4440,19 @@ public RabbitTransactionManager rabbitTransactionManager() { 从版本 2.0 开始,`concurrentConsumers`和`maxConcurrentConsumers`属性可以设置为`concurrency`属性——例如,`2-4`。 -##### [](#using-directmessagelistenercontainer)使用`DirectMessageListenerContainer` +##### 使用`DirectMessageListenerContainer` 在这个容器中,并发是基于配置的队列和`consumersPerQueue`。每个队列的每个使用者都使用一个单独的通道,并且并发性由 Rabbit 客户端库控制。默认情况下,在编写时,它使用`DEFAULT_NUM_THREADS = Runtime.getRuntime().availableProcessors() * 2`线程池。 你可以配置`taskExecutor`以提供所需的最大并发性。 -#### [](#exclusive-consumer)4.1.19。独家消费者 +#### 4.1.19.独家消费者 从版本 1.3 开始,你可以使用一个独占使用者来配置侦听器容器。这可以防止其他容器从队列中消费,直到当前使用者被取消为止。这样的容器的并发性必须是`1`。 当使用独占消费者时,其他容器尝试根据`recoveryInterval`属性从队列中消费,如果尝试失败,则记录`WARN`消息。 -#### [](#listener-queues)4.1.20。监听器容器队列 +#### 4.1.20.监听器容器队列 版本 1.3 为处理侦听器容器中的多个队列引入了许多改进。 @@ -4464,13 +4464,13 @@ public RabbitTransactionManager rabbitTransactionManager() { 如果希望永久删除队列,则应在删除到队列之前或之后更新容器,以避免将来尝试使用它。 -#### [](#resilience-recovering-from-errors-and-broker-failures)4.1.21。弹性:从错误和代理失败中恢复 +#### 4.1.21.弹性:从错误和代理失败中恢复 Spring AMQP 提供的一些关键(也是最流行的)高级特性与在协议错误或代理失败的情况下的恢复和自动重新连接有关。我们已经在本指南中看到了所有相关的组件,但是在这里将它们集合在一起并单独列出特性和恢复场景应该会有所帮助。 主要的重新连接功能由`CachingConnectionFactory`本身启用。使用`RabbitAdmin`自动声明功能通常也是有益的。此外,如果你关心保证的交付,你可能还需要在`RabbitTemplate`和`SimpleMessageListenerContainer`中使用`channelTransacted`标志,在`AcknowledgeMode.AUTO`中使用`AcknowledgeMode.AUTO`(如果你自己进行 ACK,则使用手动)标志。 -##### [](#automatic-declaration)交换、队列和绑定的自动声明 +##### 交换、队列和绑定的自动声明 `RabbitAdmin`组件可以在启动时声明交换、队列和绑定。它通过`ConnectionListener`懒洋洋地做到了这一点。因此,如果代理在启动时不存在,这并不重要。第一次使用`Connection`(例如,通过发送消息)时,侦听器将触发并应用管理功能。在侦听器中执行自动声明的另一个好处是,如果由于任何原因(例如,代理死亡,网络故障和其他原因)而丢失连接,则在重新建立连接时再次应用这些声明。 @@ -4498,7 +4498,7 @@ public DeclarableCustomizer customizer() { 另见[RabbitMQ 自动连接/拓扑恢复](#auto-recovery)。 -##### [](#retry)同步操作失败和重试选项 +##### 同步操作失败和重试选项 如果在使用`RabbitTemplate`(例如)时,在同步序列中丢失了与代理的连接, Spring AMQP 将抛出一个`AmqpException`(通常但并非总是`AmqpIOException`)。我们不会试图掩盖存在问题的事实,因此你必须能够捕捉并响应异常。如果你怀疑连接丢失(而且这不是你的错误),最简单的方法是再次尝试该操作。你可以手动完成此操作,也可以使用 Spring Retry 来处理重试(强制地或声明地)。 @@ -4521,13 +4521,13 @@ public StatefulRetryOperationsInterceptor interceptor() { 只能以这种方式配置重试功能的一个子集。更高级的功能将需要将`RetryTemplate`配置为 Spring Bean。有关可用策略及其配置的完整信息,请参见[Spring Retry Javadoc](https://docs.spring.io/spring-retry/docs/api/current/)。 -##### [](#batch-retry)使用批处理侦听器重试 +##### 使用批处理侦听器重试 不建议使用批处理侦听器配置重试,除非批处理是由生成器在单个记录中创建的。有关消费者和生产者创建的批的信息,请参见[批处理消息](#de-batching)。对于消费者创建的批处理,框架不知道批处理中的哪条消息导致了故障,因此不可能在重试结束后进行恢复。使用生产者创建的批处理,由于只有一条消息实际失败,因此可以恢复整个消息。应用程序可能想要通知自定义恢复程序在批处理中发生故障的位置,可能是通过设置抛出异常的索引属性。 批处理侦听器的重试恢复程序必须实现`MessageBatchRecoverer`。 -##### [](#async-listeners)消息侦听器和异步情况 +##### 消息侦听器和异步情况 如果`MessageListener`由于业务异常而失败,则异常由消息侦听器容器处理,然后返回到侦听另一条消息。如果故障是由已删除的连接(而不是业务异常)引起的,则必须取消并重新启动为侦听器收集消息的使用者。`SimpleMessageListenerContainer`无缝地处理此问题,并留下一个日志来表示侦听器正在重新启动。事实上,它无休止地循环,试图重新启动消费者。只有当消费者表现得非常糟糕时,它才会放弃。一个副作用是,如果代理在容器启动时关闭,它会一直尝试,直到可以建立连接为止。 @@ -4592,7 +4592,7 @@ RepublishMessageRecoverer recoverer = new RepublishMessageRecoverer(amqpTemplate 从版本 2.1 开始,将添加`ImmediateRequeueMessageRecoverer`以抛出`ImmediateRequeueAmqpException`,该命令通知侦听器容器重新请求当前失败的消息。 -##### Spring 重试的[](#exception-classification-for-spring-retry)异常分类 +##### Spring 重试的异常分类 Spring 重试在确定哪些异常可以调用重试方面具有很大的灵活性。对于所有异常,默认配置都会重试。考虑到用户异常包装在`ListenerExecutionFailedException`中,我们需要确保分类检查异常原因。默认分类器只查看顶层异常。 @@ -4600,7 +4600,7 @@ Spring 重试在确定哪些异常可以调用重试方面具有很大的灵活 要使用此分类器进行重试,你可以使用一个`SimpleRetryPolicy`,该构造函数创建了最大尝试次数,`Exception`实例的`Map`和布尔(`traverseCauses`),并将此策略注入`RetryTemplate`。 -#### [](#multi-rabbit)4.1.22。多个代理(或集群)支持 +#### 4.1.22.多个代理(或集群)支持 在单个应用程序与多个代理或代理集群之间进行通信时,版本 2.3 增加了更多的便利。在消费者方面,主要的好处是基础设施可以自动将自动声明的队列与适当的代理关联起来。 @@ -4739,13 +4739,13 @@ public ApplicationRunner runner(RabbitTemplate template, ConnectionFactoryContex } ``` -#### [](#debugging)4.1.23。调试 +#### 4.1.23.调试 Spring AMQP 提供了广泛的日志记录,特别是在`DEBUG`级别。 -如果希望监视应用程序和代理之间的 AMQP 协议,则可以使用 Wireshark 之类的工具,该工具具有一个插件来解码该协议。或者,RabbitMQ Java 客户机提供了一个非常有用的类`Tracer`。当作为`main`运行时,默认情况下,它会监听端口 5673 并连接到 LocalHost 上的端口 5672。你可以运行它并更改连接工厂配置以连接到 LocalHost 上的端口 5673。它在控制台上显示已解码的协议。有关更多信息,请参见`Tracer`Javadoc。 +如果希望监视应用程序和代理之间的 AMQP 协议,则可以使用 Wireshark 之类的工具,该工具具有一个插件来解码该协议。或者,RabbitMQ Java 客户机提供了一个非常有用的类`Tracer`。当作为`main`运行时,默认情况下,它会监听端口 5673 并连接到 LocalHost 上的端口 5672.你可以运行它并更改连接工厂配置以连接到 LocalHost 上的端口 5673.它在控制台上显示已解码的协议。有关更多信息,请参见`Tracer`Javadoc。 -### [](#stream-support)4.2。使用 RabbitMQ 流插件 +### 4.2.使用 RabbitMQ 流插件 版本 2.4 为[RabbitMQ 流插件](https://rabbitmq.com/stream.html)引入了对[RabbitMQ 流插件 Java 客户端](https://github.com/rabbitmq/rabbitmq-stream-java-client)的初始支持。 @@ -4753,11 +4753,11 @@ Spring AMQP 提供了广泛的日志记录,特别是在`DEBUG`级别。 * `StreamListenerContainer` -#### [](#sending-messages-2)4.2.1。发送消息 +#### 4.2.1.发送消息 `RabbitStreamTemplate`提供了`RabbitTemplate`功能的一个子集。 -例 1。RabbitStreamOperations +例 1.RabbitStreamOperations ``` public interface RabbitStreamOperations extends AutoCloseable { @@ -4784,7 +4784,7 @@ public interface RabbitStreamOperations extends AutoCloseable { `RabbitStreamTemplate`实现具有以下构造函数和属性: -例 2。RabbitStreamTemplate +例 2.RabbitStreamTemplate ``` public RabbitStreamTemplate(Environment environment, String streamName) { @@ -4810,7 +4810,7 @@ public synchronized void setProducerCustomizer(ProducerCustomizer producerCustom 请参阅关于自定义[Java 客户端文档](https://rabbitmq.github.io/rabbitmq-stream-java-client/stable/htmlsingle/)和`Producer`的[Java 客户端文档](https://rabbitmq.github.io/rabbitmq-stream-java-client/stable/htmlsingle/)。 -#### [](#receiving-messages-2)4.2.2。接收消息 +#### 4.2.2.接收消息 异步消息接收由`StreamListenerContainer`提供(当使用`@RabbitListener`时,`StreamRabbitListenerContainerFactory`)。 @@ -4834,7 +4834,7 @@ public interface StreamMessageListener extends MessageListener { 当使用`@RabbitListener`时,配置一个`StreamRabbitListenerContainerFactory`;此时,大多数`@RabbitListener`属性(`concurrency`等)被忽略。只支持`id`、`queues`、`autoStartup`和`containerFactory`。此外,`queues`只能包含一个流名。 -#### [](#examples)4.2.3。例子 +#### 4.2.3.例子 ``` @Bean @@ -4873,7 +4873,7 @@ void nativeMsg(Message in, Context context) { } ``` -### [](#logging)4.3。日志记录子系统 AMQP 附录 +### 4.3.日志记录子系统 AMQP 附录 该框架为一些流行的日志记录子系统提供了日志附录: @@ -4883,7 +4883,7 @@ void nativeMsg(Message in, Context context) { 通过使用日志记录子系统的常规机制来配置附录,可用的属性在下面的部分中指定。 -#### [](#common-properties)4.3.1。共同属性 +#### 4.3.1.共同属性 以下属性可与所有附录一起使用: @@ -4923,7 +4923,7 @@ void nativeMsg(Message in, Context context) { |```
clientConnectionProperties
```| ```
null
``` |用于 RabbitMQ 连接的自定义客户端属性的`key:value`对的逗号分隔列表。| | ```
addMdcAsHeaders
``` | ```
true
``` |在引入此属性之前,MDC 属性总是被添加到 RabbitMQ 消息头中。
它可能会导致大 MDC 的问题,因为 RabbitMQ 对所有头都有有限的缓冲区大小而且这个缓冲区很小。
引入这个属性是为了避免在大 MDC 的情况下出现问题。
默认情况下,这个值设置为`true`,用于向后兼容。
`false`将序列化 MDC 关闭到头中,
请注意,默认情况下,`JsonLayout`将 MDC 添加到消息中。| -#### [](#log4j-2-appender)4.3.2。log4j2 附录 +#### 4.3.2.log4j2 附录 下面的示例展示了如何配置 log4j2Appender: @@ -4945,7 +4945,7 @@ void nativeMsg(Message in, Context context) { | |从 1.6.10 和 1.7.3 版本开始,默认情况下,log4j2Appender 将消息发布到调用线程上的 RabbitMQ。
这是因为 log4j2 默认情况下不会创建线程安全事件。
如果代理关闭,则使用`maxSenderRetries`进行重试,重试之间没有延迟。
如果你希望恢复以前在单独的线程上发布消息的行为(`senderPoolSize`),则可以将`async`属性设置为`true`,但是,
,你还需要配置 log4j2 来使用`DefaultLogEventFactory`而不是`ReusableLogEventFactory`。
这样做的一种方法是设置系统属性`-Dlog4j2.enable.threadlocals=false`。
如果你使用异步发布与`ReusableLogEventFactory`,由于相声,事件很有可能被破坏。| |---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#logback-appender)4.3.3。回录附录 +#### 4.3.3.回录附录 下面的示例展示了如何配置一个 Logback Appender: @@ -4972,7 +4972,7 @@ void nativeMsg(Message in, Context context) { 从版本 2.0.0 开始,Logback`AmqpAppender`使用`encoder`选项支持[翻录编码器](https://logback.qos.ch/manual/encoders.html)。`encoder`和`layout`选项是互斥的。 -#### [](#customizing-the-messages)4.3.4。自定义消息 +#### 4.3.4.自定义消息 默认情况下,AMQP Appenders 填充以下消息属性: @@ -5047,11 +5047,11 @@ public class MyEnhancedAppender extends AmqpAppender { } ``` -#### [](#customizing-the-client-properties)4.3.5。自定义客户端属性 +#### 4.3.5.自定义客户端属性 你可以通过添加字符串属性或更复杂的属性来添加自定义客户机属性。 -##### [](#simple-string-properties)简单字符串属性 +##### 简单字符串属性 每个 Appender 都支持向 RabbitMQ 连接添加客户端属性。 @@ -5082,7 +5082,7 @@ public class MyEnhancedAppender extends AmqpAppender { 当查看连接时,这些属性会出现在 RabbitMQ 管理 UI 上。 -##### [](#advanced-technique-for-logback)回传的高级技术 +##### 回传的高级技术 你可以对 Logback Appender 进行子类。这样做可以让你在建立连接之前修改客户机连接属性。下面的示例展示了如何做到这一点: @@ -5107,7 +5107,7 @@ public class MyEnhancedAppender extends AmqpAppender { 对于字符串属性(如前面示例中所示的那些),可以使用前面的技术。子类允许添加更丰富的属性(例如添加`Map`或数字属性)。 -#### [](#providing-a-custom-queue-implementation)4.3.6。提供自定义队列实现 +#### 4.3.6.提供自定义队列实现 `AmqpAppenders`使用`BlockingQueue`将日志事件异步发布到 RabbitMQ。默认情况下,使用`LinkedBlockingQueue`。但是,你可以提供任何类型的自定义`BlockingQueue`实现。 @@ -5136,15 +5136,15 @@ log4j2Appender 支持使用[`BlockingQueueFactory`](https://logging. Apache.or ``` -### [](#sample-apps)4.4。示例应用程序 +### 4.4.示例应用程序 项目包括两个示例应用程序。第一个是一个简单的“Hello World”示例,演示了同步和异步消息接收。它为获得对基本组件的理解提供了一个很好的起点。第二个示例基于股票交易用例,以演示在现实世界的应用程序中常见的交互类型。在这一章中,我们提供了每个示例的快速演练,以便你能够关注最重要的组件。这些示例都是基于 Maven 的,因此你应该能够将它们直接导入到任何 Maven 可感知的 IDE 中(例如[SpringSource 工具套件](https://www.springsource.org/sts))。 -#### [](#hello-world-sample)4.4.1。《Hello World》样本 +#### 4.4.1.《Hello World》样本 “Hello World”示例演示了同步和异步消息接收。你可以将`spring-rabbit-helloworld`示例导入到 IDE 中,然后按照下面的讨论进行操作。 -##### [](#hello-world-sync)同步示例 +##### 同步示例 在`src/main/java`目录中,导航到`org.springframework.amqp.helloworld`包。打开`HelloWorldConfiguration`类,注意它包含类级的`@Configuration`注释,并注意方法级的一些`@Bean`注释。这是 Spring 基于 Java 的配置的一个示例。你可以阅读有关[here](https://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html#beans-java)的更多信息。 @@ -5205,7 +5205,7 @@ public static void main(String[] args) { 如果运行`Producer`,然后运行`Consumer`,则应该在控制台输出中看到`Received: Hello World`。 -##### [](#hello-world-async)异步示例 +##### 异步示例 [同步示例](#hello-world-sync)浏览了同步 Hello World 示例。这一部分描述了一个稍微更高级但功能更强大的选项。通过一些修改,Hello World 示例可以提供异步接收的示例,也称为消息驱动 POJO。实际上,有一个子包提供了以下内容:`org.springframework.amqp.samples.helloworld.async`。 @@ -5271,7 +5271,7 @@ public SimpleMessageListenerContainer listenerContainer() { `SimpleMessageListenerContainer`是一个 Spring 生命周期组件,默认情况下,它会自动启动。如果你在`Consumer`类中查找,你可以看到它的`main()`方法仅由一行引导程序组成,用于创建`ApplicationContext`。生产者的`main()`方法也是一行引导程序,因为其方法被注释为`@Scheduled`的组件也会自动启动。你可以以任何顺序启动`Producer`和`Consumer`,并且你应该每三秒钟就会看到正在发送和接收的消息。 -#### [](#stock-trading)4.4.2。股票交易 +#### 4.4.2.股票交易 股票交易示例演示了比[Hello World 样本](#hello-world-sample)更高级的消息传递场景。然而,配置是非常相似的,如果有一点更多的参与。由于我们详细介绍了 Hello World 配置,在此,我们将重点讨论使这个示例有所不同的原因。有一个服务器将市场数据(股票行情)推送到主题交换。然后,客户端可以通过绑定具有路由模式的队列来订阅市场数据提要(例如,`app.stock.quotes.nasdaq.*`)。这个演示的另一个主要功能是由客户端发起并由服务器处理的请求-回复“股票交易”交互。这涉及一个私有`replyTo`队列,该队列由客户端在订单请求消息本身内发送。 @@ -5366,7 +5366,7 @@ public StockServiceGateway stockServiceGateway() { 如果你不再运行服务器和客户机,请立即启动它们。尝试发送格式为“100tckr”的请求。在模拟“处理”请求的短暂人为延迟之后,你应该会看到一个确认消息出现在客户机上。 -#### [](#spring-rabbit-json)4.4.3。从非 Spring 份申请中接收 JSON +#### 4.4.3.从非 Spring 份申请中接收 JSON Spring 应用程序,在发送 JSON 时,将`*TypeId*`头设置为完全限定的类名,以协助接收应用程序将 JSON 转换回 Java 对象。 @@ -5374,7 +5374,7 @@ Spring 应用程序,在发送 JSON 时,将`*TypeId*`头设置为完全限定 另见[Jackson2JSONMessageConverter](#json-message-converter)以及`DefaultClassMapper`的[javadoc](https://DOCS. Spring.io/ Spring-amqp/DOCS/current/api/index.html?org/springframework/amqp/support/converter/defaultclassmapper.html)。 -### [](#testing)4.5。测试支持 +### 4.5.测试支持 为异步应用程序编写集成一定比测试更简单的应用程序更复杂。当`@RabbitListener`注释之类的抽象出现在图片中时,这就变得更加复杂了。问题是如何验证在发送消息后,侦听器是否如预期的那样接收到了消息。 @@ -5382,7 +5382,7 @@ Spring 应用程序,在发送 JSON 时,将`*TypeId*`头设置为完全限定 Spring AMQP 版本 1.6 引入了`spring-rabbit-test`JAR,它为测试这些更复杂的场景中的一些提供了支持。预计该项目将随着时间的推移而扩展,但我们需要社区反馈来为帮助测试所需的功能提供建议。请使用[JIRA](https://jira.spring.io/browse/AMQP)或[GitHub 问题](https://github.com/spring-projects/spring-amqp/issues)提供此类反馈。 -#### [](#spring-rabbit-test)4.5.1。@SpringRabbitTest +#### 4.5.1.@SpringRabbitTest 使用此注释将基础设施 bean 添加到 Spring test`ApplicationContext`。在使用`@SpringBootTest`时,这是不必要的,因为 Spring boot 的自动配置将添加 bean。 @@ -5398,7 +5398,7 @@ Spring AMQP 版本 1.6 引入了`spring-rabbit-test`JAR,它为测试这些更 此外,还添加了与`@EnableRabbit`相关的 bean(以支持`@RabbitListener`)。 -例 4。JUnit5 示例 +例 4.JUnit5 示例 ``` @SpringJunitConfig @@ -5431,7 +5431,7 @@ public class MyRabbitTests { 使用 JUnit4,将`@SpringJunitConfig`替换为`@RunWith(SpringRunnner.class)`。 -#### [](#mockito-answer)4.5.2。mockito`Answer`实现 +#### 4.5.2.mockito`Answer`实现 目前有两个`Answer`实现来帮助测试。 @@ -5483,7 +5483,7 @@ assertEquals("thingthing", thing.thing("thing")); 当与[`@RabbitListenerTest`和`RabbitListenerTestHarness`]结合使用时,使用`harness.getLambdaAnswerFor("listenerId", true, …​)`可以为侦听器获得正确构造的答案。 -#### [](#test-harness)4.5.3。`@RabbitListenerTest`和`RabbitListenerTestHarness` +#### 4.5.3.`@RabbitListenerTest`和`RabbitListenerTestHarness` 将一个`@Configuration`类注释为`@RabbitListenerTest`,会导致框架将标准`RabbitListenerAnnotationBeanPostProcessor`替换为一个名为`RabbitListenerTestHarness`的子类(它还通过`@EnableRabbit`启用`@RabbitListener`检测)。 @@ -5644,7 +5644,7 @@ public class MyTests { | |当将自定义`Answer`s 与线束一起使用时,为了正确地进行操作,这样的答案应该是子类`ForwardsInvocation`并从线束中获得实际的侦听器(而不是间谍)(`getDelegate("myListener")`)并调用

参见所提供的[mockito`Answer`实现](#mockito-answer)源代码的示例。| |---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#test-template)4.5.4。使用`TestRabbitTemplate` +#### 4.5.4.使用`TestRabbitTemplate` `TestRabbitTemplate`用于执行一些基本的集成测试,而不需要代理。在测试用例中将其添加为`@Bean`时,它会发现上下文中的所有侦听器容器,无论是声明为`@Bean`还是``还是使用`@RabbitListener`注释。它目前仅支持按队列名进行路由。模板从容器中提取消息侦听器,并直接在测试线程上调用它。返回回复的侦听器支持请求-回复消息(`sendAndReceive`methods)。 @@ -5756,11 +5756,11 @@ public class TestRabbitTemplateTests { } ``` -#### [](#junit-rules)4.5.5。JUnit4`@Rules` +#### 4.5.5.JUnit4`@Rules` Spring AMQP1.7 版及以后版本提供了一个名为`spring-rabbit-junit`的附加 JAR。此 JAR 包含两个实用程序`@Rule`实例,用于运行 JUnit4 测试时使用。关于 JUnit5 测试,请参见[JUnit5 条件](#junit5-conditions)。 -##### [](#using-brokerrunning)使用`BrokerRunning` +##### 使用`BrokerRunning` `BrokerRunning`提供了一种机制,当代理不运行时(默认情况下,在`localhost`上),让测试成功。 @@ -5780,7 +5780,7 @@ public static void tearDown() { 有几个`isRunning…​`静态方法,例如`isBrokerAndManagementRunning()`,它验证代理是否启用了管理插件。 -###### [](#brokerRunning-configure)配置规则 +###### 配置规则 有时,如果没有代理,你希望测试失败,比如夜间的 CI 构建。要在运行时禁用该规则,请将一个名为`RABBITMQ_SERVER_REQUIRED`的环境变量设置为`true`。 @@ -5829,7 +5829,7 @@ public CachingConnectionFactory rabbitConnectionFactory() { } ``` -##### [](#using-longrunningintegrationtest)使用`LongRunningIntegrationTest` +##### 使用`LongRunningIntegrationTest` `LongRunningIntegrationTest`是一条禁用长时间运行测试的规则。你可能希望在开发人员系统上使用该规则,但要确保在例如 Nightly CI 构建上禁用该规则。 @@ -5842,11 +5842,11 @@ public LongRunningIntegrationTest longTests = new LongRunningIntegrationTest(); 要在运行时禁用该规则,请将一个名为`RUN_LONG_INTEGRATION_TESTS`的环境变量设置为`true`。 -#### [](#junit5-conditions)4.5.6。JUnit5 条件 +#### 4.5.6.JUnit5 条件 2.0.2 版引入了对 JUnit5 的支持。 -##### [](#using-the-rabbitavailable-annotation)使用`@RabbitAvailable`注释 +##### 使用`@RabbitAvailable`注释 这个类级注释类似于在[JUnit4`@Rules`]中讨论的`BrokerRunning``@Rule`(#JUnit-rules)。它由`RabbitAvailableCondition`处理。 @@ -5983,7 +5983,7 @@ public class RabbitTemplateMPPIntegrationTests { } ``` -##### [](#using-the-longrunning-annotation)使用`@LongRunning`注释 +##### 使用`@LongRunning`注释 与`LongRunningIntegrationTest`JUnit4`@Rule`类似,除非将环境变量(或系统属性)设置为`true`,否则此注释将导致跳过测试。下面的示例展示了如何使用它: @@ -6001,21 +6001,21 @@ public class SimpleMessageListenerContainerLongTests { 默认情况下,变量是`RUN_LONG_INTEGRATION_TESTS`,但你可以在注释的`value`属性中指定变量名。 -## [](#spring-integration-reference)5。 Spring 整合-参考 +## 5. Spring 整合-参考 参考文档的这一部分快速介绍了 Spring 集成项目中的 AMQP 支持。 -### [](#spring-integration-amqp)5.1。 Spring 集成 AMQP 支持 +### 5.1. Spring 集成 AMQP 支持 这一简短的章节涵盖了 Spring 集成和 Spring AMQP 项目之间的关系。 -#### [](#spring-integration-amqp-introduction)5.1.1。导言 +#### 5.1.1.导言 [Spring Integration](https://www.springsource.org/spring-integration)项目包括基于 Spring AMQP 项目的 AMQP 通道适配器和网关。这些适配器是在 Spring 集成项目中开发和发布的。在 Spring 集成中,“通道适配器”是单向的,而“网关”是双向的。我们提供了入站通道适配器、出站通道适配器、入站网关和出站网关。 由于 AMQP 适配器是 Spring 集成发行版的一部分,所以文档可以作为 Spring 集成发行版的一部分使用。我们在这里提供了主要功能的简要概述。有关更多详细信息,请参见[Spring Integration Reference Guide](https://docs.spring.io/spring-integration/reference/htmlsingle/)。 -#### [](#inbound-channel-adapter)5.1.2。入站通道适配器 +#### 5.1.2.入站通道适配器 要从队列接收 AMQP 消息,可以配置``。下面的示例展示了如何配置入站通道适配器: @@ -6025,7 +6025,7 @@ public class SimpleMessageListenerContainerLongTests { connection-factory="rabbitConnectionFactory"/> ``` -#### [](#outbound-channel-adapter)5.1.3。出站通道适配器 +#### 5.1.3.出站通道适配器 要将 AMQP 消息发送到 Exchange,可以配置``。你可以在 Exchange 名称之外提供一个“路由密钥”。下面的示例展示了如何定义出站通道适配器: @@ -6036,7 +6036,7 @@ public class SimpleMessageListenerContainerLongTests { amqp-template="rabbitTemplate"/> ``` -#### [](#inbound-gateway)5.1.4。入站网关 +#### 5.1.4.入站网关 要从队列接收 AMQP 消息并响应其应答地址,可以配置``。下面的示例展示了如何定义入站网关: @@ -6047,7 +6047,7 @@ public class SimpleMessageListenerContainerLongTests { connection-factory="rabbitConnectionFactory"/> ``` -#### [](#outbound-gateway)5.1.5。出站网关 +#### 5.1.5.出站网关 要将 AMQP 消息发送到 Exchange 并从远程客户端接收回响应,可以配置``。你可以在 Exchange 名称之外提供一个“路由密钥”。下面的示例展示了如何定义出站网关: @@ -6059,47 +6059,47 @@ public class SimpleMessageListenerContainerLongTests { amqp-template="rabbitTemplate"/> ``` -## [](#resources)6。其他资源 +## 6.其他资源 除了这个参考文档,还有许多其他资源可以帮助你了解 AMQP。 -### [](#further-reading)6.1。进一步阅读 +### 6.1.进一步阅读 -对于那些不熟悉 AMQP 的人来说,[规格](https://www.amqp.org/resources/download)实际上是很有可读性的。当然,它是权威的信息来源, Spring AMQP 代码对于任何熟悉该规范的人都应该很容易理解。我们目前对 RabbitMQ 支持的实现基于他们的 2.8.x 版本,它正式支持 AMQP0.8 和 0.9.1。我们建议阅读 0.9.1 文档。 +对于那些不熟悉 AMQP 的人来说,[规格](https://www.amqp.org/resources/download)实际上是很有可读性的。当然,它是权威的信息来源, Spring AMQP 代码对于任何熟悉该规范的人都应该很容易理解。我们目前对 RabbitMQ 支持的实现基于他们的 2.8.x 版本,它正式支持 AMQP0.8 和 0.9.1.我们建议阅读 0.9.1 文档。 在 RabbitMQ[开始](https://www.rabbitmq.com/how.html)页面上有很多很棒的文章、演示文稿和博客。由于这是 Spring AMQP 当前唯一受支持的实现,因此我们还建议将其作为所有与代理相关的关注的一般起点。 -## [](#change-history)附录 A:变更历史 +## 附录 A:变更历史 这一节描述了在版本发生变化时所做的更改。 -### [](#current-release)a.1。当前版本 +### a.1.当前版本 见[What’s New](#whats-new)。 -### [](#previous-whats-new)a.2。以前的版本 +### a.2.以前的版本 -#### [](#changes-in-2-3-since-2-2)a.2.1。自 2.2 以来 2.3 的变化 +#### a.2.1.自 2.2 以来 2.3 的变化 本部分描述了版本 2.2 和版本 2.3 之间的更改。有关以前版本的更改,请参见[变更历史](#change-history)。 -##### [](#connection-factory-changes)连接工厂变更 +##### 连接工厂变更 现在提供了两个额外的连接工厂。有关更多信息,请参见[选择连接工厂](#choosing-factory)。 -##### [](#rabbitlistener-changes-2)`@RabbitListener`变化 +##### `@RabbitListener`变化 现在可以指定回复内容类型。有关更多信息,请参见[回复 ContentType](#reply-content-type)。 -##### [](#message-converter-changes)消息转换器更改 +##### 消息转换器更改 如果`ObjectMapper`配置了自定义反序列化器,则`Jackson2JMessageConverter`s 现在可以反序列化抽象类(包括接口)。有关更多信息,请参见[反序列化抽象类](#jackson-abstract)。 -##### [](#testing-changes)测试更改 +##### 测试更改 提供了一个新的注释`@SpringRabbitTest`,用于在不使用`SpringBootTest`时自动配置一些基础设施 bean。有关更多信息,请参见[@SpringRabbitTest](#spring-rabbit-test)。 -##### [](#rabbittemplate-changes)RabbitTemplate 更改 +##### RabbitTemplate 更改 模板的`ReturnCallback`已被重构为`ReturnsCallback`,以便在 lambda 表达式中更简单地使用。有关更多信息,请参见[相关发布者确认并返回](#template-confirms)。 @@ -6107,7 +6107,7 @@ public class SimpleMessageListenerContainerLongTests { 当使用直接回复时,你现在可以配置模板,这样服务器就不需要返回与回复相关的数据。有关更多信息,请参见[RabbitMQ 直接回复](#direct-reply-to)。 -##### [](#listener-container-changes)侦听器容器更改 +##### 侦听器容器更改 现在可以使用一个新的侦听器容器属性`consumeDelay`;当使用[RabbitMQ 分片插件](https://github.com/rabbitmq/rabbitmq-sharding)时,该属性很有帮助。 @@ -6117,23 +6117,23 @@ public class SimpleMessageListenerContainerLongTests { 有关更多信息,请参见[消息侦听器容器配置](#containerAttributes)。 -##### [](#messagepostprocessor-changes)MessagePostProcessor 更改 +##### MessagePostProcessor 更改 压缩`MessagePostProcessor`s 现在使用逗号来分隔多个内容编码,而不是冒号。解压器可以处理这两种格式,但是,如果你使用这个版本生成的消息被 2.2.12 之前的版本使用,那么你应该将压缩器配置为使用旧的分隔符。有关更多信息,请参见[修改消息-压缩和更多](#post-processing)中的重要注释。 -##### [](#multiple-broker-support-improvements)多个代理支持改进 +##### 多个代理支持改进 有关更多信息,请参见[多个代理(或集群)支持](#multi-rabbit)。 -##### [](#republishmessagerecoverer-changes)RepublishMessageRecoverer 更改 +##### RepublishMessageRecoverer 更改 不提供此 recoverer 的支持发布服务器确认的新子类。有关更多信息,请参见[消息侦听器和异步情况](#async-listeners)。 -#### [](#changes-in-2-2-since-2-1)a.2.2。自 2.1 以来 2.2 的变化 +#### a.2.2.自 2.1 以来 2.2 的变化 本部分描述了版本 2.1 和版本 2.2 之间的更改。 -##### [](#package-changes)软件包更改 +##### 软件包更改 以下类/接口已从`org.springframework.amqp.rabbit.core.support`移至`org.springframework.amqp.rabbit.batch`: @@ -6145,23 +6145,23 @@ public class SimpleMessageListenerContainerLongTests { 此外,`ListenerExecutionFailedException`已从`org.springframework.amqp.rabbit.listener.exception`移至`org.springframework.amqp.rabbit.support`。 -##### [](#dependency-changes)依赖项更改 +##### 依赖项更改 JUnit(4)现在是一个可选的依赖项,并且将不再以传递依赖项的形式出现。 `spring-rabbit-junit`模块现在是**编译**模块中的`spring-rabbit-test`依赖项,以便在仅使用单个`spring-rabbit-test`时获得更好的目标应用程序开发体验,我们获得了 AMQP 组件的完整测试实用程序堆栈。 -##### [](#breaking-api-changes)“breaking”API 变更 +##### “breaking”API 变更 -JUnit(5)`RabbitAvailableCondition.getBrokerRunning()`现在返回一个`BrokerRunningSupport`实例,而不是一个`BrokerRunning`实例,后者取决于 JUnit4。它有相同的 API,所以只需要更改任何引用的类名。有关更多信息,请参见[JUnit5 条件](#junit5-conditions)。 +JUnit(5)`RabbitAvailableCondition.getBrokerRunning()`现在返回一个`BrokerRunningSupport`实例,而不是一个`BrokerRunning`实例,后者取决于 JUnit4.它有相同的 API,所以只需要更改任何引用的类名。有关更多信息,请参见[JUnit5 条件](#junit5-conditions)。 -##### [](#listenercontainer-changes)ListenerContainer 更改 +##### ListenerContainer 更改 默认情况下,即使确认模式是手动的,具有致命异常的消息现在也会被拒绝,并且不会重新请求。有关更多信息,请参见[异常处理](#exception-handling)。 监听器的性能现在可以使用微米计`Timer`s 进行监视。有关更多信息,请参见[监视监听器性能](#micrometer)。 -##### [](#rabbitlistener-changes-3)@RabbitListener 更改 +##### @RabbitListener 更改 现在可以在每个侦听器上配置`executor`,覆盖工厂配置,以更容易地识别与侦听器关联的线程。现在可以使用注释的`ackMode`属性覆盖容器工厂的`acknowledgeMode`属性。有关更多信息,请参见[覆盖集装箱工厂的属性](#listener-property-overrides)。 @@ -6183,7 +6183,7 @@ Spring 数据投影接口现在由`Jackson2JsonMessageConverter`支持。有关 现在可以配置`ReplyPostProcessor`,以便在发送回复消息之前对其进行修改。有关更多信息,请参见[回复管理](#async-annotation-driven-reply)。 -##### [](#amqp-logging-appenders-changes)AMQP 日志附录更改 +##### AMQP 日志附录更改 log4j 和 logback`AmqpAppender`s 现在支持`verifyHostname`SSL 选项。 @@ -6193,17 +6193,17 @@ Appenders 现在支持`SaslConfig`属性。 有关更多信息,请参见[日志记录子系统 AMQP 附录](#logging)。 -##### [](#messagelisteneradapter-changes)MessageListenerAdapter 更改 +##### MessageListenerAdapter 更改 `MessageListenerAdapter`现在提供了一个新的`buildListenerArguments(Object, Channel, Message)`方法来构建一个参数数组,这些参数将被传递到目标侦听器中,而一个旧的参数将被弃用。有关更多信息,请参见[`MessageListenerAdapter`]。 -##### [](#exchangequeue-declaration-changes)交换/队列声明更改 +##### 交换/队列声明更改 用于创建`ExchangeBuilder`和`QueueBuilder`用于由`Exchange`声明的`Queue`对象的 fluent API 现在支持“众所周知”的参数。有关更多信息,请参见[用于队列和交换的 Builder API](#builder-api)。 `RabbitAdmin`有一个新的属性`explicitDeclarationsOnly`。有关更多信息,请参见[有条件声明](#conditional-declaration)。 -##### [](#connection-factory-changes-2)连接工厂变更 +##### 连接工厂变更 `CachingConnectionFactory`有一个新的属性`shuffleAddresses`。当提供代理节点地址列表时,将在创建连接之前对列表进行调整,以便尝试连接的顺序是随机的。有关更多信息,请参见[连接到集群](#cluster)。 @@ -6211,13 +6211,13 @@ Appenders 现在支持`SaslConfig`属性。 此外,现在使用`ConfirmType`枚举来指定发布服务器确认类型,而不是使用两个互斥的 setter 方法。 -当启用 SSL 时,`RabbitConnectionFactoryBean`现在默认使用 TLS1.2。有关更多信息,请参见[`RabbitConnectionFactoryBean`和配置 SSL]。 +当启用 SSL 时,`RabbitConnectionFactoryBean`现在默认使用 TLS1.2.有关更多信息,请参见[`RabbitConnectionFactoryBean`和配置 SSL]。 -##### [](#new-messagepostprocessor-classes)新的 MessagePostProcessor 类 +##### 新的 MessagePostProcessor 类 当消息内容编码设置为`deflate`时,分别添加了类`DeflaterPostProcessor`和`InflaterPostProcessor`以支持压缩和解压。 -##### [](#other-changes)其他更改 +##### 其他更改 `Declarables`对象(用于声明多个队列、交换、绑定)现在为每个类型都有一个过滤 getter。有关更多信息,请参见[声明交换、队列和绑定的集合](#collection-declaration)。 @@ -6229,40 +6229,40 @@ Appenders 现在支持`SaslConfig`属性。 现在支持恢复失败的生产者创建的批处理。有关更多信息,请参见[使用批处理侦听器重试](#batch-retry)。 -#### [](#changes-in-2-1-since-2-0)a.2.3。自 2.0 以来 2.1 的变化 +#### a.2.3.自 2.0 以来 2.1 的变化 -##### [](#amqp-client-library)AMQP 客户库 +##### AMQP 客户库 Spring AMQP 现在使用由 RabbitMQ 团队提供的`amqp-client`库的 5.4.x 版本。默认情况下,此客户端配置了自动恢复功能。见[RabbitMQ 自动连接/拓扑恢复](#auto-recovery)。 | |从版本 4.0 开始,客户端默认支持自动恢复。
虽然与此功能兼容, Spring AMQP 有自己的恢复机制,并且客户端恢复功能通常不需要。
我们建议禁用`amqp-client`自动恢复,为了避免在代理可用但连接尚未恢复时获得`AutoRecoverConnectionNotCurrentlyOpenException`实例。
从 1.7.1 版本开始, Spring AMQP 禁用它,除非你显式地创建自己的 RabbitMQ 连接工厂并将其提供给`CachingConnectionFactory`。
RabbitMQ`ConnectionFactory`由`RabbitConnectionFactoryBean`创建的实例还具有默认禁用的选项。| |---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#package-changes-2)软件包更改 +##### 软件包更改 某些类已转移到不同的包。大多数是内部类,不会影响用户应用程序。两个例外是`ChannelAwareMessageListener`和`RabbitListenerErrorHandler`。这些接口现在在`org.springframework.amqp.rabbit.listener.api`中。 -##### [](#publisher-confirms-changes)Publisher 确认更改 +##### Publisher 确认更改 当存在未完成的确认时,启用了发布者确认的通道不会返回到缓存中。有关更多信息,请参见[相关发布者确认并返回](#template-confirms)。 -##### [](#listener-container-factory-improvements)监听器容器工厂改进 +##### 监听器容器工厂改进 现在,你可以使用侦听器容器工厂来创建任何侦听器容器,而不仅仅是用于`@RabbitListener`注释或`@RabbitListenerEndpointRegistry`注释的侦听器容器。有关更多信息,请参见[使用集装箱工厂](#using-container-factories)。 `ChannelAwareMessageListener`现在继承自`MessageListener`。 -##### [](#broker-event-listener)Broker 事件侦听器 +##### Broker 事件侦听器 引入`BrokerEventListener`以将选定的代理事件发布为`ApplicationEvent`实例。有关更多信息,请参见[代理事件监听器](#broker-events)。 -##### [](#rabbitadmin-changes-2)RabbitAdmin 更改 +##### RabbitAdmin 更改 `RabbitAdmin`发现类型为`Declarables`的 bean(这是`Declarable`-`Queue`,`Exchange`和`Binding`对象的容器)并在代理上声明所包含的对象。不鼓励用户使用声明`>`(和其他)的旧机制,而应该使用`Declarables`bean。默认情况下,旧机制将被禁用。有关更多信息,请参见[声明交换、队列和绑定的集合](#collection-declaration)。 `AnonymousQueue`实例现在声明为`x-queue-master-locator`,默认设置为`client-local`,以确保队列是在应用程序所连接的节点上创建的。有关更多信息,请参见[配置代理](#broker-configuration)。 -##### [](#rabbittemplate-changes-2)RabbitTemplate 更改 +##### RabbitTemplate 更改 现在,你可以使用`noLocalReplyConsumer`选项配置`RabbitTemplate`,以便在`sendAndReceive()`操作中控制用于回复消费者的`noLocal`标志。有关更多信息,请参见[请求/回复消息](#request-reply)。 @@ -6272,70 +6272,70 @@ Spring AMQP 现在使用由 RabbitMQ 团队提供的`amqp-client`库的 5.4.x 现在,你可以指定一个`ErrorHandler`,当发送回复时发生异常(例如,延迟回复)时,在使用`DirectReplyToMessageListenerContainer`(默认)请求/回复时要调用的`ErrorHandler`。参见`setReplyErrorHandler`上的`RabbitTemplate`。(也是从 2.0.11 开始)。 -##### [](#message-conversion)消息转换 +##### 消息转换 我们引入了一个新的`Jackson2XmlMessageConverter`,以支持将消息从 XML 格式转换为 XML 格式。有关更多信息,请参见[`Jackson2XmlMessageConverter`](#Jackson2xml)。 -##### [](#management-rest-api-2)管理 REST API +##### 管理 REST API 现在不赞成`RabbitManagementTemplate`,而赞成直接使用`com.rabbitmq.http.client.Client`(或`com.rabbitmq.http.client.ReactorNettyClient`)。有关更多信息,请参见[RabbitMQ REST API](#management-rest-api)。 -##### [](#rabbitlistener-changes-4)`@RabbitListener`变化 +##### `@RabbitListener`变化 现在可以将侦听器容器工厂配置为`RetryTemplate`,也可以在发送回复时使用`RecoveryCallback`。有关更多信息,请参见[启用监听器端点注释](#async-annotation-driven-enable)。 -##### [](#async-rabbitlistener-return)异步`@RabbitListener`返回 +##### 异步`@RabbitListener`返回 `@RabbitListener`方法现在可以返回`ListenableFuture`或`Mono`。有关更多信息,请参见[异步`@RabbitListener`返回类型]。 -##### [](#connection-factory-bean-changes)连接工厂 Bean 变更 +##### 连接工厂 Bean 变更 默认情况下,`RabbitConnectionFactoryBean`现在调用`enableHostnameVerification()`。要恢复到以前的行为,请将`enableHostnameVerification`属性设置为`false`。 -##### [](#connection-factory-changes-3)连接工厂变更 +##### 连接工厂变更 现在,`CachingConnectionFactory`无条件地禁用底层 RabbitMQ`ConnectionFactory`中的自动恢复,即使构造函数中提供了预先配置的实例。虽然已经采取措施使 Spring AMQP 与自动恢复兼容,但在仍然存在问题的情况下出现了某些情况。 Spring AMQP 自 1.0.0 以来已经有了自己的恢复机制,并且不需要使用由客户端提供的恢复。虽然仍然有可能在`CachingConnectionFactory`后启用该功能(使用`cachingConnectionFactory.getRabbitConnectionFactory()``.setAutomaticRecoveryEnabled()`),**我们强烈建议你不要这样做。**被构造。如果在直接使用客户端工厂(而不是使用 Spring AMQP 组件)时需要自动恢复连接,我们建议你使用单独的 RabbitMQ。 -##### [](#listener-container-changes-2)侦听器容器更改 +##### 侦听器容器更改 如果存在`x-death`报头,那么默认的`ConditionalRejectingErrorHandler`现在将完全丢弃导致致命错误的消息。有关更多信息,请参见[异常处理](#exception-handling)。 -##### [](#immediate-requeue)立即请求 +##### 立即请求 引入了一个新的`ImmediateRequeueAmqpException`来通知侦听器容器消息必须重新排队。要使用此功能,需要添加一个新的`ImmediateRequeueMessageRecoverer`实现。 有关更多信息,请参见[消息侦听器和异步情况](#async-listeners)。 -#### [](#changes-in-2-0-since-1-7)a.2.4。自 1.7 以来 2.0 的变化 +#### a.2.4.自 1.7 以来 2.0 的变化 -##### [](#using-cachingconnectionfactory)使用`CachingConnectionFactory` +##### 使用`CachingConnectionFactory` 从版本 2.0.2 开始,你可以将`RabbitTemplate`配置为使用与侦听器容器使用的不同的连接。这一变化避免了当生产商因任何原因而受阻时,消费者陷入僵局。有关更多信息,请参见[使用单独的连接](#separate-connection)。 -##### [](#amqp-client-library-2)AMQP 客户库 +##### AMQP 客户库 Spring AMQP 现在使用由 RabbitMQ 团队提供的`amqp-client`库的新的 5.0.x 版本。默认情况下,此客户端配置了自动恢复。见[RabbitMQ 自动连接/拓扑恢复](#auto-recovery)。 | |从版本 4.0 开始,客户端默认启用自动恢复。
虽然兼容此功能, Spring AMQP 有自己的恢复机制,并且客户端恢复功能一般不需要。
我们建议你禁用`amqp-client`自动恢复,为了避免在代理可用但连接尚未恢复时获得`AutoRecoverConnectionNotCurrentlyOpenException`实例。
从 1.7.1 版本开始, Spring AMQP 禁用它,除非你显式地创建自己的 RabbitMQ 连接工厂并将其提供给`CachingConnectionFactory`。
RabbitMQ`ConnectionFactory`由`RabbitConnectionFactoryBean`创建的实例还具有默认禁用的选项。| |---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#general-changes)一般变化 +##### 一般变化 现在`ExchangeBuilder`默认情况下构建持久交换。在`@QeueueBinding`中使用的`@Exchange`注释也默认声明持久交换。在`@RabbitListener`中使用的`@Queue`注释默认情况下声明持久队列(如果命名)和非持久队列(如果匿名)。有关更多信息,请参见[用于队列和交换的 Builder API](#builder-api)和[注释驱动的监听器端点](#async-annotation-driven)。 -##### [](#deleted-classes)删除类 +##### 删除类 `UniquelyNameQueue`不再提供。使用唯一的名称创建持久的非自动删除队列是不常见的。这个类已被删除。如果你需要它的功能,请使用`new Queue(UUID.randomUUID().toString())`。 -##### [](#new-listener-container)新建侦听器容器 +##### 新建侦听器容器 已在现有的`SimpleMessageListenerContainer`旁边添加了`DirectMessageListenerContainer`。有关选择使用哪个容器以及如何配置它们的信息,请参见[选择容器](#choose-container)和[消息侦听器容器配置](#containerAttributes)。 -##### [](#log4j-appender)log4j 附录 +##### log4j 附录 由于 log4j 的报废,此附录不再可用。有关可用日志附录的信息,请参见[日志记录子系统 AMQP 附录](#logging)。 -##### [](#rabbittemplate-changes-3)`RabbitTemplate`变更 +##### `RabbitTemplate`变更 | |以前,如果一个非事务性事务`RabbitTemplate`运行在事务性侦听器容器线程上,那么它就参与了一个现有事务。,
这是一个严重的错误,
但是,用户可能依赖于这种行为,
从 1.6.2 版本开始,你必须在模板上设置`channelTransacted`布尔,才能让它参与容器事务。| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| @@ -6348,13 +6348,13 @@ Spring AMQP 现在使用由 RabbitMQ 团队提供的`amqp-client`库的新的 5. 现在可以使用`RabbitTemplate`在专用通道上执行多个操作。有关更多信息,请参见[作用域操作](#scoped-operations)。 -##### [](#listener-adapter)侦听器适配器 +##### 侦听器适配器 一个方便的`FunctionalInterface`可用于使用带有`MessageListenerAdapter`的 lambdas。有关更多信息,请参见[`MessageListenerAdapter`](#message-listener-adapter)。 -##### [](#listener-container-changes-3)侦听器容器更改 +##### 侦听器容器更改 -###### [](#prefetch-default-value)预取默认值 +###### 预取默认值 预取默认值过去是 1,这可能导致有效消费者的利用率不足。默认的预取值现在是 250,这应该会使消费者在大多数常见的情况下都很忙,从而提高吞吐量。 @@ -6363,37 +6363,37 @@ Spring AMQP 现在使用由 RabbitMQ 团队提供的`amqp-client`库的新的 5. 有关 Prefetch 的更多背景信息,请参见这篇关于[RabbitMQ 中的消费者利用](https://www.rabbitmq.com/blog/2014/04/14/finding-bottlenecks-with-rabbitmq-3-3/)的文章和这篇关于[排队论](https://www.rabbitmq.com/blog/2012/05/11/some-queuing-theory-throughput-latency-and-bandwidth/)的文章。 -###### [](#message-count)消息计数 +###### 消息计数 以前,对于容器发出的消息,`MessageProperties.getMessageCount()`返回`0`。此属性仅当你使用`basicGet`(例如,从`RabbitTemplate.receive()`方法)时才适用,并且现在对于容器消息初始化为`null`。 -###### [](#transaction-rollback-behavior)事务回滚行为 +###### 事务回滚行为 无论是否配置了事务管理器,事务回滚上的消息重新队列现在都是一致的。有关更多信息,请参见[关于回滚收到的消息的说明](#transaction-rollback)。 -###### [](#shutdown-behavior)关机行为 +###### 关机行为 如果容器线程不响应`shutdownTimeout`内的关机,则默认情况下将强制关闭通道。有关更多信息,请参见[消息侦听器容器配置](#containerAttributes)。 -###### [](#after-receive-message-post-processors)接收消息后处理程序 +###### 接收消息后处理程序 如果`afterReceiveMessagePostProcessors`属性中的`MessagePostProcessor`返回`null`,则该消息将被丢弃(并在适当的情况下进行确认)。 -##### [](#connection-factory-changes-4)连接工厂变更 +##### 连接工厂变更 连接和通道侦听器接口现在提供了一种机制来获取有关异常的信息。有关更多信息,请参见[连接和通道侦听器](#connection-channel-listeners)和[发布是异步的——如何检测成功和失败](#publishing-is-async)。 现在提供了一个新的`ConnectionNameStrategy`,用于从`AbstractConnectionFactory`填充目标 RabbitMQ 连接的特定于应用程序的标识。有关更多信息,请参见[连接和资源管理](#connections)。 -##### [](#retry-changes)重试更改 +##### 重试更改 不再提供`MissingMessageIdAdvice`。它的功能现在是内置的。有关更多信息,请参见[同步操作中的故障和重试选项](#retry)。 -##### [](#anonymous-queue-naming)匿名队列命名 +##### 匿名队列命名 默认情况下,`AnonymousQueues`现在使用默认的`Base64UrlNamingStrategy`来命名,而不是简单的`UUID`字符串。有关更多信息,请参见[`AnonymousQueue`]。 -##### [](#rabbitlistener-changes-5)`@RabbitListener`变更 +##### `@RabbitListener`变更 现在可以在`@RabbitListener`注释中提供简单的队列声明(仅绑定到默认的交换)。有关更多信息,请参见[注释驱动的监听器端点](#async-annotation-driven)。 @@ -6411,144 +6411,144 @@ Spring AMQP 现在使用由 RabbitMQ 团队提供的`amqp-client`库的新的 5. 从版本 2.0.3 开始,类级`@RabbitHandler`上的一个`@RabbitListener`注释可以被指定为默认值。有关更多信息,请参见[多方法侦听器](#annotation-method-selection)。 -##### [](#container-conditional-rollback)容器条件回滚 +##### 容器条件回滚 当使用外部事务管理器(例如 JDBC)时,当你为容器提供事务属性时,现在支持基于规则的回滚。现在,当你使用事务建议时,它也更加灵活。有关更多信息,请参见[条件回滚](#conditional-rollback)。 -##### [](#remove-jackson-1-x-support)删除 Jackson1.x 支持 +##### 删除 Jackson1.x 支持 在以前的版本中不推荐的 Jackson`1.x`转换器和相关组件现在已被删除。你可以使用基于 Jackson2.x 的类似组件。有关更多信息,请参见[Jackson2JSONMessageConverter](#json-message-converter)。 -##### [](#json-message-converter-2)JSON 消息转换器 +##### JSON 消息转换器 当将入站 JSON 消息的`*TypeId*`设置为`Hashtable`时,现在默认的转换类型是`LinkedHashMap`。在此之前,它是`Hashtable`。要恢复到`Hashtable`,可以在`DefaultClassMapper`上使用`setDefaultMapType`。 -##### [](#xml-parsers)XML 解析器 +##### XML 解析器 在解析`Queue`和`Exchange`XML 组件时,如果存在`id`属性,则解析器不再将`name`属性值注册为 Bean 别名。有关更多信息,请参见[关于`id`和`name`属性的注释]。 -##### [](#blocked-connection)阻塞连接 +##### 阻塞连接 现在可以将`com.rabbitmq.client.BlockedListener`注入`org.springframework.amqp.rabbit.connection.Connection`对象。此外,当连接被代理阻塞或解除锁定时,`ConnectionBlockedEvent`和`ConnectionUnblockedEvent`事件由`ConnectionFactory`发出。 有关更多信息,请参见[连接和资源管理](#connections)。 -#### [](#changes-in-1-7-since-1-6)a.2.5。1.7 自 1.6 以来的变化 +#### a.2.5.1.7 自 1.6 以来的变化 -##### [](#amqp-client-library-3)AMQP 客户库 +##### AMQP 客户库 Spring AMQP 现在使用由 RabbitMQ 团队提供的`amqp-client`库的新的 4.0.x 版本。默认情况下,此客户端配置了自动恢复功能。见[RabbitMQ 自动连接/拓扑恢复](#auto-recovery)。 | |4.0.x 客户端默认支持自动恢复。
虽然与此功能兼容, Spring AMQP 有自己的恢复机制,并且客户端恢复功能通常不需要。
我们建议禁用`amqp-client`自动恢复,为了避免在代理可用但连接尚未恢复时获得`AutoRecoverConnectionNotCurrentlyOpenException`实例。
从 1.7.1 版本开始, Spring AMQP 禁用它,除非你显式地创建自己的 RabbitMQ 连接工厂,并将其提供给`CachingConnectionFactory`。
RabbitMQ`ConnectionFactory`由`RabbitConnectionFactoryBean`创建的实例还具有默认禁用的选项。| |---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#log4j-2-upgrade)log4j2 升级 +##### log4j2 升级 最小的 log4j2 版本(对于`AmqpAppender`)现在是`2.7`。该框架不再与以前的版本兼容。有关更多信息,请参见[日志记录子系统 AMQP 附录](#logging)。 -##### [](#logback-appender-2)翻录附录 +##### 翻录附录 默认情况下,此附录不再捕获调用方数据(方法、行号)。你可以通过设置`includeCallerData`配置选项重新启用它。有关可用日志附录的信息,请参见[日志记录子系统 AMQP 附录](#logging)。 -##### [](#spring-retry-upgrade) Spring 重试升级 +##### Spring 重试升级 重试的最低版本现在是`1.2`。该框架不再与以前的版本兼容。 -###### [](#shutdown-behavior-2)关机行为 +###### 关机行为 你现在可以将`forceCloseChannel`设置为`true`,这样,如果容器线程在`shutdownTimeout`内没有响应关机,则将强制关闭通道,从而导致任何未加锁的消息重新排队。有关更多信息,请参见[消息侦听器容器配置](#containerAttributes)。 -##### [](#fasterxml-jackson-upgrade)fasterxml Jackson 升级 +##### fasterxml Jackson 升级 Jackson 的最低版本现在是`2.8`。该框架不再与以前的版本兼容。 -##### [](#junit-rules-2)JUnit`@Rules` +##### JUnit`@Rules` 以前由框架内部使用的规则现在可以在一个名为`spring-rabbit-junit`的单独 JAR 中使用。有关更多信息,请参见[JUnit4`@Rules`]。 -##### [](#container-conditional-rollback-2)容器条件回滚 +##### 容器条件回滚 当你使用外部事务管理器(例如 JDBC)时,当你为容器提供事务属性时,现在支持基于规则的回滚。现在,当你使用事务建议时,它也更加灵活。 -##### [](#connection-naming-strategy)连接命名策略 +##### 连接命名策略 现在提供了一个新的`ConnectionNameStrategy`,用于从`AbstractConnectionFactory`填充目标 RabbitMQ 连接的特定于应用程序的标识。有关更多信息,请参见[连接和资源管理](#connections)。 -##### [](#listener-container-changes-4)侦听器容器更改 +##### 侦听器容器更改 -###### [](#transaction-rollback-behavior-2)事务回滚行为 +###### 事务回滚行为 现在,无论是否配置了事务管理器,都可以将事务回滚上的消息重新排队配置为一致。有关更多信息,请参见[关于回滚收到的消息的说明](#transaction-rollback)。 -#### [](#earlier-releases)a.2.6。早期版本 +#### a.2.6.早期版本 有关以前版本的更改,请参见[以前的版本](#previous-whats-new)。 -#### [](#changes-in-1-6-since-1-5)a.2.7。自 1.5 以来 1.6 的变化 +#### a.2.7.自 1.5 以来 1.6 的变化 -##### [](#testing-support)测试支持 +##### 测试支持 现在提供了一个新的测试支持库。有关更多信息,请参见[测试支持](#testing)。 -##### [](#builder)建设者 +##### 建设者 现在可以使用为配置`Queue`和`Exchange`对象提供流畅 API 的构建器。有关更多信息,请参见[用于队列和交换的 Builder API](#builder-api)。 -##### [](#namespace-changes)名称空间变更 +##### 名称空间变更 -###### [](#connection-factory-2)连接工厂 +###### 连接工厂 现在可以将`thread-factory`添加到连接工厂 Bean 声明中——例如,用于命名由`amqp-client`库创建的线程。有关更多信息,请参见[连接和资源管理](#connections)。 当你使用`CacheMode.CONNECTION`时,现在可以限制允许的连接总数。有关更多信息,请参见[连接和资源管理](#connections)。 -###### [](#queue-definitions)队列定义 +###### 队列定义 现在可以为匿名队列提供命名策略。有关更多信息,请参见[`AnonymousQueue`]。 -##### [](#listener-container-changes-5)侦听器容器更改 +##### 侦听器容器更改 -###### [](#idle-message-listener-detection)空闲消息侦听器检测 +###### 空闲消息侦听器检测 现在可以将侦听器容器配置为在空闲时发布`ApplicationEvent`实例。有关更多信息,请参见[检测空闲异步消费者](#idle-containers)。 -###### [](#mismatched-queue-detection)不匹配队列检测 +###### 不匹配队列检测 默认情况下,当侦听器容器启动时,如果检测到具有不匹配属性或参数的队列,则容器会记录异常,但会继续侦听。容器现在具有一个名为`mismatchedQueuesFatal`的属性,如果在启动过程中检测到问题,该属性将阻止容器(和上下文)启动。如果稍后检测到问题,例如从连接失败中恢复后,它还会停止容器。有关更多信息,请参见[消息侦听器容器配置](#containerAttributes)。 -###### [](#listener-container-logging)侦听器容器日志记录 +###### 侦听器容器日志记录 现在,侦听器容器将其`beanName`提供给内部`SimpleAsyncTaskExecutor`作为`threadNamePrefix`。它对日志分析很有用。 -###### [](#default-error-handler)默认错误处理程序 +###### 默认错误处理程序 默认的错误处理程序(`ConditionalRejectingErrorHandler`)现在认为不可恢复的`@RabbitListener`异常是致命的。有关更多信息,请参见[异常处理](#exception-handling)。 -##### [](#autodeclare-and-rabbitadmin-instances)`AutoDeclare`和`RabbitAdmin`实例 +##### `AutoDeclare`和`RabbitAdmin`实例 有关在应用程序上下文中使用`RabbitAdmin`实例对该选项语义的一些更改,请参见[消息侦听器容器配置](#containerAttributes)(`autoDeclare`)。 -##### [](#amqptemplate-receive-with-timeout)`AmqpTemplate`:超时接收 +##### `AmqpTemplate`:超时接收 已经为`AmqpTemplate`及其`RabbitTemplate`实现引入了许多带有`timeout`的新`receive()`方法。有关更多信息,请参见[轮询消费者](#polling-consumer)。 -##### [](#using-asyncrabbittemplate)使用`AsyncRabbitTemplate` +##### 使用`AsyncRabbitTemplate` 引入了一个新的`AsyncRabbitTemplate`。此模板提供了许多发送和接收方法,其中返回值为`ListenableFuture`,以后可以使用它同步或异步地获得结果。有关更多信息,请参见[异步兔子模板](#async-template)。 -##### [](#rabbittemplate-changes-4)`RabbitTemplate`变化 +##### `RabbitTemplate`变化 1.4.1 引入了在代理支持[直接回复](https://www.rabbitmq.com/direct-reply-to.html)时使用[直接回复](https://www.rabbitmq.com/direct-reply-to.html)的能力。这比为每个回复使用临时队列更有效。此版本允许你通过将`useTemporaryReplyQueues`属性设置为`true`来覆盖此默认行为并使用临时队列。有关更多信息,请参见[RabbitMQ 直接回复](#direct-reply-to)。 `RabbitTemplate`现在支持`user-id-expression`(在使用 Java 配置时`userIdExpression`)。有关更多信息,请参见[经过验证的用户 ID RabbitMQ 文档](https://www.rabbitmq.com/validated-user-id.html)和[已验证的用户 ID](#template-user-id)。 -##### [](#message-properties)消息属性 +##### 消息属性 -###### [](#using-correlationid)使用`CorrelationId` +###### 使用`CorrelationId` 消息属性`correlationId`现在可以是`String`。有关更多信息,请参见[消息属性转换器](#message-properties-converters)。 -###### [](#long-string-headers)长字符串标题 +###### 长字符串标题 以前,`DefaultMessagePropertiesConverter`将比长字符串限制(缺省 1024)更长的头转换为`DataInputStream`(实际上,它引用了`LongString`实例的`DataInputStream`)。在输出时,这个头没有被转换(除了转换为字符串——例如,通过在流上调用`toString()`,`[[email protected]](/cdn-cgi/l/email-protection)`)。 @@ -6556,7 +6556,7 @@ Jackson 的最低版本现在是`2.8`。该框架不再与以前的版本兼容 有关更多信息,请参见[消息属性转换器](#message-properties-converters)。 -###### [](#inbound-delivery-mode)入站交付模式 +###### 入站交付模式 `deliveryMode`属性不再映射到`MessageProperties.deliveryMode`。如果使用相同的`MessageProperties`对象发送出站消息,则此更改将避免意外传播。相反,入站`deliveryMode`标头被映射到`MessageProperties.receivedDeliveryMode`。 @@ -6566,7 +6566,7 @@ Jackson 的最低版本现在是`2.8`。该框架不再与以前的版本兼容 有关更多信息,请参见[带注释的端点方法签名](#async-annotation-driven-enable-signature)。 -###### [](#inbound-user-id)入站用户 ID +###### 入站用户 ID `user_id`属性不再映射到`MessageProperties.userId`。如果使用相同的`MessageProperties`对象发送出站消息,则此更改将避免意外传播。相反,入站`userId`头被映射到`MessageProperties.receivedUserId`。 @@ -6576,220 +6576,220 @@ Jackson 的最低版本现在是`2.8`。该框架不再与以前的版本兼容 有关更多信息,请参见[带注释的端点方法签名](#async-annotation-driven-enable-signature)。 -##### [](#rabbitadmin-changes-3)`RabbitAdmin`变化 +##### `RabbitAdmin`变化 -###### [](#declaration-failures)宣告失败 +###### 宣告失败 以前,`ignoreDeclarationFailures`标志仅对通道上的`IOException`生效(例如不匹配的参数)。它现在对任何例外情况生效(例如`TimeoutException`)。此外,现在只要声明失败,就会发布`DeclarationExceptionEvent`。`RabbitAdmin`Last declaration 事件也可以作为属性`lastDeclarationExceptionEvent`使用。有关更多信息,请参见[配置代理](#broker-configuration)。 -##### [](#rabbitlistener-changes-6)`@RabbitListener`变更 +##### `@RabbitListener`变更 -###### [](#multiple-containers-for-each-bean)每个容器有多个 Bean +###### 每个容器有多个 Bean 当你使用 Java8 或更高版本时,你现在可以将多个`@RabbitListener`注释添加到`@Bean`类或它们的方法中。当使用 Java7 或更早版本时,你可以使用`@RabbitListeners`容器注释来提供相同的功能。有关更多信息,请参见[`@Repeatable``@RabbitListener`]。 -###### [](#sendto-spel-expressions)`@SendTo`spel 表达式 +###### `@SendTo`spel 表达式 `@SendTo`用于路由不带`replyTo`属性的回复,现在可以根据请求/回复计算 SPEL 表达式。有关更多信息,请参见[回复管理](#async-annotation-driven-reply)。 -###### [](#queuebinding-improvements)`@QueueBinding`改进 +###### `@QueueBinding`改进 现在可以在`@QueueBinding`注释中指定队列、交换和绑定的参数。现在`@QueueBinding`支持报头交换。有关更多信息,请参见[注释驱动的监听器端点](#async-annotation-driven)。 -##### [](#delayed-message-exchange-2)延迟消息交换 +##### 延迟消息交换 Spring AMQP 现在拥有对 RabbitMQ 延迟消息交换插件的一流支持。有关更多信息,请参见[延迟的消息交换](#delayed-message-exchange)。 -##### [](#exchange-internal-flag)交易所内部标志 +##### 交易所内部标志 任何`Exchange`定义现在都可以标记为`internal`,并且`RabbitAdmin`在声明交易所时将该值传递给代理。有关更多信息,请参见[配置代理](#broker-configuration)。 -##### [](#cachingconnectionfactory-changes)`CachingConnectionFactory`变化 +##### `CachingConnectionFactory`变化 -###### [](#cachingconnectionfactory-cache-statistics)`CachingConnectionFactory`缓存统计信息 +###### `CachingConnectionFactory`缓存统计信息 `CachingConnectionFactory`现在在运行时和 JMX 上提供缓存属性。有关更多信息,请参见[运行时缓存属性](#runtime-cache-properties)。 -###### [](#accessing-the-underlying-rabbitmq-connection-factory)访问底层 RabbitMQ 连接工厂 +###### 访问底层 RabbitMQ 连接工厂 添加了一个新的 getter 以提供对底层工厂的访问。例如,你可以使用此 getter 添加自定义连接属性。有关更多信息,请参见[添加自定义客户端连接属性](#custom-client-props)。 -###### [](#channel-cache)通道缓存 +###### 通道缓存 -默认通道缓存大小已从 1 增加到 25。有关更多信息,请参见[连接和资源管理](#connections)。 +默认通道缓存大小已从 1 增加到 25.有关更多信息,请参见[连接和资源管理](#connections)。 此外,`SimpleMessageListenerContainer`不再调整缓存大小,使其至少与`concurrentConsumers`的数量一样大——这是多余的,因为容器使用者通道永远不会被缓存。 -##### [](#using-rabbitconnectionfactorybean)使用`RabbitConnectionFactoryBean` +##### 使用`RabbitConnectionFactoryBean` 工厂 Bean 现在公开一个属性,以便将客户机连接属性添加到由结果工厂创建的连接中。 -##### [](#java-deserialization-2)Java 反序列化 +##### Java 反序列化 现在,你可以在使用 Java 反序列化时配置一个允许类的“允许列表”。如果你接受来自不受信任的源的带有序列化 Java 对象的消息,那么你应该考虑创建一个允许的列表。有关更多信息,请参见[Java 反序列化](#java-deserialization)。 -##### [](#json-messageconverter)JSON `MessageConverter` +##### JSON `MessageConverter` 对 JSON 消息转换器的改进现在允许使用消息头中没有类型信息的消息。有关更多信息,请参见[带注释方法的消息转换](#async-annotation-conversion)和[Jackson2JSONMessageConverter](#json-message-converter)。 -##### [](#logging-appenders)日志附录 +##### 日志附录 -###### [](#log4j-2)log4j2 +###### log4j2 添加了一个 log4j2Appender,现在可以将 Appenders 配置为`addresses`属性,以连接到代理群集。 -###### [](#client-connection-properties)客户端连接属性 +###### 客户端连接属性 现在可以将自定义客户端连接属性添加到 RabbitMQ 连接中。 有关更多信息,请参见[日志记录子系统 AMQP 附录](#logging)。 -#### [](#changes-in-1-5-since-1-4)a.2.8。1.5 自 1.4 以来的变化 +#### a.2.8.1.5 自 1.4 以来的变化 -##### [](#spring-erlang-is-no-longer-supported)`spring-erlang`不再支持 +##### `spring-erlang`不再支持 `spring-erlang`JAR 不再包含在分发版中。用[RabbitMQ REST API](#management-rest-api)代替。 -##### [](#cachingconnectionfactory-changes-2)`CachingConnectionFactory`变化 +##### `CachingConnectionFactory`变化 -###### [](#empty-addresses-property-in-cachingconnectionfactory)中的空地址属性`CachingConnectionFactory` +###### 中的空地址属性`CachingConnectionFactory` 以前,如果连接工厂配置了主机和端口,但也为`addresses`提供了一个空字符串,则会忽略主机和端口。现在,一个空的`addresses`字符串被处理为与`null`相同的字符串,并且使用了主机和端口。 -###### [](#uri-constructor)URI 构造函数 +###### URI 构造函数 `CachingConnectionFactory`有一个附加的构造函数,带有`URI`参数,用于配置代理连接。 -###### [](#connection-reset)连接重置 +###### 连接重置 添加了一个名为`resetConnection()`的新方法,让用户重置连接(或连接)。例如,你可以使用它在失败转移到次要代理之后重新连接到主代理。这**是吗?**会影响进程内操作。现有的`destroy()`方法做的完全相同,但是新方法的名称不那么令人生畏。 -##### [](#properties-to-control-container-queue-declaration-behavior)控制容器队列声明行为的属性 +##### 控制容器队列声明行为的属性 当监听器容器使用者启动时,他们尝试被动地声明队列,以确保它们在代理上可用。在此之前,如果这些声明失败(例如,因为队列不存在),或者当一个 HA 队列被移动时,重试逻辑被固定为以五秒为间隔的三次重试尝试。如果队列仍然不存在,则行为由`missingQueuesFatal`属性控制(默认:`true`)。此外,对于配置为监听多个队列的容器,如果只有一个队列子集可用,那么使用者将在 60 秒的固定时间间隔内重试丢失的队列。 `declarationRetries`、`failedDeclarationRetryInterval`和`retryDeclarationInterval`属性现在是可配置的。有关更多信息,请参见[消息侦听器容器配置](#containerAttributes)。 -##### [](#class-package-change)类包更改 +##### 类包更改 将`RabbitGatewaySupport`类从`o.s.amqp.rabbit.core.support`移动到`o.s.amqp.rabbit.core`。 -##### [](#defaultmessagepropertiesconverter-changes)`DefaultMessagePropertiesConverter`变化 +##### `DefaultMessagePropertiesConverter`变化 你现在可以配置`DefaultMessagePropertiesConverter`以确定将`LongString`转换为`String`而不是转换为`DataInputStream`的最大长度。转换器有一个替代的构造函数,它将值作为一个限制。以前,这个限制是以`1024`字节进行硬编码的。(也可在 1.4.4 中获得)。 -##### [](#rabbitlistener-improvements)`@RabbitListener`改进 +##### `@RabbitListener`改进 -###### [](#queuebinding-for-rabbitlistener)`@QueueBinding`表示`@RabbitListener` +###### `@QueueBinding`表示`@RabbitListener` `bindings`属性已被添加到`@RabbitListener`注释中,作为与`queues`属性的互斥,以允许`queue`的规范,其`exchange`和`binding`用于代理上的`RabbitAdmin`声明。 -###### [](#spel-in-sendto)spel in`@SendTo` +###### spel in`@SendTo` `@RabbitListener`的默认回复地址(`@SendTo`)现在可以是 SPEL 表达式。 -###### [](#multiple-queue-names-through-properties)通过属性获得多个队列名称 +###### 通过属性获得多个队列名称 现在可以使用 SPEL 和属性占位符的组合来为侦听器指定多个队列。 有关更多信息,请参见[注释驱动的监听器端点](#async-annotation-driven)。 -##### [](#automatic-exchange-queue-and-binding-declaration)自动交换、队列和绑定声明 +##### 自动交换、队列和绑定声明 现在可以声明定义这些实体集合的 bean,并且`RabbitAdmin`将内容添加到它在建立连接时声明的实体列表中。有关更多信息,请参见[声明交换、队列和绑定的集合](#collection-declaration)。 -##### [](#rabbittemplate-changes-5)`RabbitTemplate`变更 +##### `RabbitTemplate`变更 -###### [](#reply-address-added)`reply-address`已添加 +###### `reply-address`已添加 已将`reply-address`属性添加到``组件中,作为替代`reply-queue`。有关更多信息,请参见[请求/回复消息](#request-reply)。(也可以在 1.4.4 中作为`RabbitTemplate`上的 setter)。 -###### [](#blocking-receive-methods)阻塞`receive`方法 +###### 阻塞`receive`方法 `RabbitTemplate`现在支持`receive`和`convertAndReceive`方法中的阻塞。有关更多信息,请参见[轮询消费者](#polling-consumer)。 -###### [](#mandatory-with-sendandreceive-methods)强制使用`sendAndReceive`方法 +###### 强制使用`sendAndReceive`方法 当使用`mandatory`和`convertSendAndReceive`方法设置`mandatory`标志时,如果无法传递请求消息,则调用线程将抛出`AmqpMessageReturnedException`。有关更多信息,请参见[回复超时](#reply-timeout)。 -###### [](#improper-reply-listener-configuration)不正确的应答侦听器配置 +###### 不正确的应答侦听器配置 当使用命名的应答队列时,框架将尝试验证应答侦听器容器的正确配置。 有关更多信息,请参见[回复监听器容器](#reply-listener)。 -##### [](#rabbitmanagementtemplate-added)`RabbitManagementTemplate`已添加 +##### `RabbitManagementTemplate`已添加 引入了`RabbitManagementTemplate`,通过使用其[管理插件 Name](https://www.rabbitmq.com/management.html)提供的 REST API 来监视和配置 RabbitMQ 代理。有关更多信息,请参见[RabbitMQ REST API](#management-rest-api)。 -##### [](#listener-container-bean-names-xml)侦听器容器 Bean 名称 +##### 侦听器容器 Bean 名称 | |``元素上的`id`属性已被删除。
从这个版本开始,单独使用``子元素上的`id`来命名为每个侦听器元素创建的侦听器容器 Bean。将应用

正常的 Spring Bean 名称重载。
如果稍后的``与现有的 Bean 相同的`id`进行解析,新的定义覆盖了现有的定义。
以前, Bean 名称是由`id`和``元素的``属性组成的。
当迁移到此版本时,如果你的`id`元素上有`id`属性,删除它们并在子元素``上设置`id`。| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| 但是,为了支持作为一个组开始和停止容器,添加了一个新的`group`属性。定义此属性时,由此元素创建的容器将添加到具有此名称的 Bean,类型为`Collection`。你可以迭代这个组来启动和停止容器。 -##### [](#class-level-rabbitlistener)class-level`@RabbitListener` +##### class-level`@RabbitListener` 现在可以在类级别应用`@RabbitListener`注释。与新的`@RabbitHandler`方法注释一起,这允许你基于有效负载类型选择处理程序方法。有关更多信息,请参见[多方法侦听器](#annotation-method-selection)。 -##### [](#simplemessagelistenercontainer-backoff-support)`SimpleMessageListenerContainer`:Backoff 支持 +##### `SimpleMessageListenerContainer`:Backoff 支持 现在可以为`SimpleMessageListenerContainer`启动恢复提供`BackOff`实例。有关更多信息,请参见[消息侦听器容器配置](#containerAttributes)。 -##### [](#channel-close-logging-2)通道关闭日志记录 +##### 通道关闭日志记录 介绍了一种控制信道关闭日志级别的机制。见[记录通道关闭事件](#channel-close-logging)。 -##### [](#application-events)应用程序事件 +##### 应用程序事件 现在,当使用者失败时,`SimpleMessageListenerContainer`将发出应用程序事件。有关更多信息,请参见[消费者活动](#consumer-events)。 -##### [](#consumer-tag-configuration)消费者标签配置 +##### 消费者标签配置 以前,异步消费者的消费者标记是由代理生成的。通过这个版本,现在可以向侦听器容器提供命名策略。见[消费者标签](#consumerTags)。 -##### [](#using-messagelisteneradapter)使用`MessageListenerAdapter` +##### 使用`MessageListenerAdapter` `MessageListenerAdapter`现在支持队列名称(或使用者标记)到方法名称的映射,以根据接收消息的队列确定调用哪个委托方法。 -##### [](#localizedqueueconnectionfactory-added)`LocalizedQueueConnectionFactory`已添加 +##### `LocalizedQueueConnectionFactory`已添加 `LocalizedQueueConnectionFactory`是一个新的连接工厂,它连接到集群中实际驻留镜像队列的节点。 参见[Queue Affinity 和`LocalizedQueueConnectionFactory`]。 -##### [](#anonymous-queue-naming-2)匿名队列命名 +##### 匿名队列命名 从版本 1.5.3 开始,你现在可以控制`AnonymousQueue`名称的生成方式。有关更多信息,请参见[`AnonymousQueue`]。 -#### [](#changes-in-1-4-since-1-3)a.2.9。自 1.3 以来 1.4 的变化 +#### a.2.9.自 1.3 以来 1.4 的变化 -##### [](#rabbitlistener-annotation)`@RabbitListener`注释 +##### `@RabbitListener`注释 -POJO 侦听器可以使用`@RabbitListener`进行注释,也可以使用`@EnableRabbit`或``。 Spring 此功能需要框架 4.1。有关更多信息,请参见[注释驱动的监听器端点](#async-annotation-driven)。 +POJO 侦听器可以使用`@RabbitListener`进行注释,也可以使用`@EnableRabbit`或``。 Spring 此功能需要框架 4.1.有关更多信息,请参见[注释驱动的监听器端点](#async-annotation-driven)。 -##### [](#rabbitmessagingtemplate-added)`RabbitMessagingTemplate`已添加 +##### `RabbitMessagingTemplate`已添加 -一个新的`RabbitMessagingTemplate`允许你通过使用`spring-messaging``Message`实例与 RabbitMQ 进行交互。在内部,它使用`RabbitTemplate`,你可以将其配置为常规配置。 Spring 此功能需要框架 4.1。有关更多信息,请参见[消息传递集成](#template-messaging)。 +一个新的`RabbitMessagingTemplate`允许你通过使用`spring-messaging``Message`实例与 RabbitMQ 进行交互。在内部,它使用`RabbitTemplate`,你可以将其配置为常规配置。 Spring 此功能需要框架 4.1.有关更多信息,请参见[消息传递集成](#template-messaging)。 -##### [](#listener-container-missingqueuesfatal-attribute)侦听器容器`missingQueuesFatal`属性 +##### 侦听器容器`missingQueuesFatal`属性 1.3.5 在`SimpleMessageListenerContainer`上引入了`missingQueuesFatal`属性。这现在在侦听器容器名称空间元素上可用。见[消息侦听器容器配置](#containerAttributes)。 -##### [](#rabbittemplate-confirmcallback-interface)RabbitTemplate`ConfirmCallback`接口 +##### RabbitTemplate`ConfirmCallback`接口 这个接口上的`confirm`方法有一个额外的参数,称为`cause`。当可用时,此参数包含否定确认的原因。见[相关发布者确认并返回](#template-confirms)。 -##### [](#rabbitconnectionfactorybean-added)`RabbitConnectionFactoryBean`已添加 +##### `RabbitConnectionFactoryBean`已添加 `RabbitConnectionFactoryBean`创建由`CachingConnectionFactory`使用的底层 RabbitMQ`ConnectionFactory`。这允许使用 Spring 的依赖注入配置 SSL 选项。见[配置底层客户机连接工厂](#connection-factory)。 -##### [](#using-cachingconnectionfactory-2)使用`CachingConnectionFactory` +##### 使用`CachingConnectionFactory` 现在,`CachingConnectionFactory`允许将`connectionTimeout`设置为名称空间中的一个属性或属性。它在底层 RabbitMQ`ConnectionFactory`上设置属性。见[配置底层客户机连接工厂](#connection-factory)。 -##### [](#log-appender)日志附录 +##### 日志附录 已引入了注销`org.springframework.amqp.rabbit.logback.AmqpAppender`。它提供了类似于`org.springframework.amqp.rabbit.log4j.AmqpAppender`的选项。有关更多信息,请参见这些类的 Javadoc。 @@ -6797,23 +6797,23 @@ log4j`AmqpAppender`现在支持`deliveryMode`属性(`PERSISTENT`或`NON_PERSIS Appender 还支持在发送前修改`Message`——例如,允许添加自定义标头。子类应该覆盖`postProcessMessageBeforeSend()`。 -##### [](#listener-queues-2)侦听器队列 +##### 侦听器队列 现在,默认情况下,侦听器容器会在启动过程中重新声明任何丢失的队列。已向``添加了一个新的`auto-declare`属性,以防止这些重新声明。参见[`auto-delete`队列]。 -##### [](#rabbittemplate-mandatory-and-connectionfactoryselector-expressions)`RabbitTemplate`:`mandatory`和`connectionFactorySelector`表达式 +##### `RabbitTemplate`:`mandatory`和`connectionFactorySelector`表达式 而`mandatoryExpression`,`sendConnectionFactorySelectorExpression`和`receiveConnectionFactorySelectorExpression`spel 表达式`s properties have been added to `RabbitTemplate`. The `mandatoryexpression` is used to evaluate a `强制` boolean value against each request message when a `returncall` is in use. See [Correlated Publisher Confirms and Returns](#template-confirms). The `sendConnectionygt=“factorexpression<4214"/>factortortoryr=“actorpressionmentfactortortorypresslausion`的``现在支持解析``子元素。现在,你可以使用`key/value`属性对配置``中的``(以便在单个标头上进行匹配)或使用``子元素(允许在多个标头上进行匹配)。这些选择是相互排斥的。见[头交换](#headers-exchange)。 -##### [](#routing-connection-factory-2)路由连接工厂 +##### 路由连接工厂 引入了一个新的`SimpleRoutingConnectionFactory`。它允许配置`ConnectionFactories`映射,以确定在运行时使用的目标`ConnectionFactory`。见[路由连接工厂](#routing-connection-factory)。 -##### [](#messagebuilder-and-messagepropertiesbuilder)`MessageBuilder`和`MessagePropertiesBuilder` +##### `MessageBuilder`和`MessagePropertiesBuilder` 现在提供了用于构建消息或消息属性的“Fluent API”。见[Message Builder API](#message-builder)。 -##### [](#retryinterceptorbuilder-change)`RetryInterceptorBuilder`变化 +##### `RetryInterceptorBuilder`变化 现在提供了用于构建侦听器容器重试拦截器的“Fluent API”。见[同步操作中的故障和重试选项](#retry)。 -##### [](#republishmessagerecoverer-added)`RepublishMessageRecoverer`已添加 +##### `RepublishMessageRecoverer`已添加 提供了这个新的`MessageRecoverer`,以允许在重试用完时将失败的消息发布到另一个队列(包括消息头中的堆栈跟踪信息)。见[消息侦听器和异步情况](#async-listeners)。 -##### [](#default-error-handler-since-1-3-2)默认错误处理程序(自 1.3.2 起) +##### 默认错误处理程序(自 1.3.2 起) 已将默认的`ConditionalRejectingErrorHandler`添加到侦听器容器中。此错误处理程序检测到致命的消息转换问题,并指示容器拒绝该消息,以防止代理继续重新交付不可转换的消息。见[异常处理](#exception-handling)。 -##### [](#listener-container-missingqueuesfatal-property-since-1-3-5)侦听器容器“missingqueuesfatal”属性(自 1.3.5) +##### 侦听器容器“missingqueuesfatal”属性(自 1.3.5) `SimpleMessageListenerContainer`现在有一个名为`missingQueuesFatal`的属性(默认值:`true`)。以前,排不上队总是致命的。见[消息侦听器容器配置](#containerAttributes)。 -#### [](#changes-to-1-2-since-1-1)a.2.11。自 1.1 以来对 1.2 的更改 +#### a.2.11.自 1.1 以来对 1.2 的更改 -##### [](#rabbitmq-version)RabbitMQ 版本 +##### RabbitMQ 版本 Spring AMQP 现在默认使用 RabbitMQ3.1.x(但保留了与早期版本的兼容性)。对于 RabbitMQ3.1.x——联邦交换和`RabbitTemplate`上的`immediate`属性不再支持的特性,已经添加了某些异议。 -##### [](#rabbit-admin-2)兔子管理员 +##### 兔子管理员 `RabbitAdmin`现在提供了一个选项,可以在声明失败时让 Exchange、Queue 和 binding 声明继续。以前,所有的声明都是在失败时停止的。通过设置`ignore-declaration-exceptions`,将记录此类异常(在`WARN`级别),但会继续进行进一步的声明。这可能有用的一个例子是,当队列声明失败时,原因是一个稍微不同的`ttl`设置,该设置通常会阻止其他声明继续进行。 `RabbitAdmin`现在提供了一个名为`getQueueProperties()`的附加方法。你可以使用它来确定代理上是否存在队列(对于不存在的队列,返回`null`)。此外,它返回队列中当前消息的数量以及当前消费者的数量。 -##### [](#rabbit-template)兔子模板 +##### 兔子模板 以前,当`…​sendAndReceive()`方法与固定的应答队列一起使用时,将使用两个自定义标头来进行相关数据以及保留和恢复应答队列信息。在此版本中,默认情况下使用标准消息属性(`correlationId`),尽管你可以指定要使用的自定义属性。此外,嵌套的`replyTo`信息现在被保留在模板内部,而不是使用自定义标头。 `immediate`属性已弃用。在使用 RabbitMQ3.0.x 或更高版本时,不能设置此属性。 -##### [](#json-message-converters)JSON 消息转换器 +##### JSON 消息转换器 现在提供了一个 Jackson2.x`MessageConverter`,以及使用 Jackson1.x 的现有转换器。 -##### [](#automatic-declaration-of-queues-and-other-items)队列和其他项的自动声明 +##### 队列和其他项的自动声明 以前,在声明队列、交换和绑定时,你无法定义声明使用哪个连接工厂。每个`RabbitAdmin`通过使用其连接声明所有组件。 从这个版本开始,你现在可以将声明限制为特定的`RabbitAdmin`实例。见[有条件声明](#conditional-declaration)。 -##### [](#amqp-remoting)AMQP Remoting +##### AMQP Remoting 现在提供了用于使用 Spring 远程技术的设施,使用 AMQP 作为 RPC 调用的传输。有关更多信息,请参见[Spring Remoting with AMQP](#remoting) -##### [](#requested-heart-beats)请求心跳 +##### 请求心跳 一些用户要求在 Spring AMQP`CachingConnectionFactory`上公开底层客户机连接工厂的`requestedHeartBeats`属性。这是现在可用的。在此之前,有必要将 AMQP 客户端工厂配置为单独的 Bean,并在`CachingConnectionFactory`中提供对它的引用。 -#### [](#changes-to-1-1-since-1-0)a.2.12。自 1.0 以来对 1.1 的更改 +#### a.2.12.自 1.0 以来对 1.1 的更改 -##### [](#general)一般 +##### 一般 Spring-AMQP 现在是用 Gradle 构建的。 @@ -6953,7 +6953,7 @@ Spring-AMQP 现在是用 Gradle 构建的。 增加了对死信交换和死信队列的支持。 -##### [](#amqp-log4j-appender)AMQP log4j Appender +##### AMQP log4j Appender 添加一个选项,以支持将消息 ID 添加到已记录的消息中。