AMQP 规范描述了如何使用该协议在代理上配置队列、交换和绑定。 这些操作(可从 0.8 及更高版本移植)存在于包的接口中。 该类的 RabbitMQ 实现位于包中。AmqpAdminorg.springframework.amqp.coreRabbitAdminorg.springframework.amqp.rabbit.coreSpring中文文档

该接口基于使用 Spring AMQP 域抽象,如以下列表所示:AmqpAdminSpring中文文档

public interface AmqpAdmin {

    // Exchange Operations

    void declareExchange(Exchange exchange);

    void deleteExchange(String exchangeName);

    // Queue Operations

    Queue declareQueue();

    String declareQueue(Queue queue);

    void deleteQueue(String queueName);

    void deleteQueue(String queueName, boolean unused, boolean empty);

    void purgeQueue(String queueName, boolean noWait);

    // Binding Operations

    void declareBinding(Binding binding);

    void removeBinding(Binding binding);

    Properties getQueueProperties(String queueName);

}

该方法返回有关队列的一些有限信息(消息计数和使用者计数)。 返回的属性的键在 (、 和 ) 中作为常量提供。 RabbitMQ REST API 在对象中提供了更多信息。getQueueProperties()RabbitTemplateQUEUE_NAMEQUEUE_MESSAGE_COUNTQUEUE_CONSUMER_COUNTQueueInfoSpring中文文档

no-arg 方法在代理上定义一个队列,该队列的名称是自动生成的。 此自动生成的队列的其他属性是 、 和 。declareQueue()exclusive=trueautoDelete=truedurable=falseSpring中文文档

该方法接受一个对象并返回已声明队列的名称。 如果提供的属性为空,则代理使用生成的名称声明队列。 该名称将返回给调用方。 该名称也会添加到 的属性中。 您只能通过直接调用 以编程方式使用此功能。 在应用程序上下文中以声明方式定义队列时,如果管理员使用自动声明,则可以将 name 属性设置为(空字符串)。 然后,代理创建名称。 从版本 2.1 开始,侦听器容器可以使用此类型的队列。 有关更多信息,请参阅容器和代理命名队列declareQueue(Queue queue)QueuenameQueueStringactualNameQueueRabbitAdmin""Spring中文文档

这与框架生成唯一 () 名称并将 和 、 设置为 相反。 具有空(或缺失)属性的 A 始终创建一个 .AnonymousQueueUUIDdurablefalseexclusiveautoDeletetrue<rabbit:queue/>nameAnonymousQueueSpring中文文档

请参阅 AnonymousQueue 以了解为什么优先于代理生成的队列名称以及 如何控制名称的格式。 从版本 2.1 开始,默认情况下声明匿名队列的参数设置为。 这可确保在应用程序连接到的节点上声明队列。 声明性队列必须具有固定名称,因为它们可能会在上下文中的其他位置被引用,例如在 侦听器如以下示例所示:AnonymousQueueQueue.X_QUEUE_LEADER_LOCATORclient-localSpring中文文档

<rabbit:listener-container>
    <rabbit:listener ref="listener" queue-names="#{someQueue.name}" />
</rabbit:listener-container>

此接口的 RabbitMQ 实现是 ,当使用 Spring XML 进行配置时,它类似于以下示例:RabbitAdminSpring中文文档

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

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

当缓存模式为(默认模式)时,实现会自动延迟声明在同一 中声明的队列、交换和绑定。 一旦向代理打开 a,就会声明这些组件。 有一些命名空间功能使这非常方便——例如, 在 Stocks 示例应用程序中,我们有以下内容:CachingConnectionFactoryCHANNELRabbitAdminApplicationContextConnectionSpring中文文档

<rabbit:queue id="tradeQueue"/>

<rabbit:queue id="marketDataQueue"/>

<fanout-exchange name="broadcast.responses"
                 xmlns="http://www.springframework.org/schema/rabbit">
    <bindings>
        <binding queue="tradeQueue"/>
    </bindings>
</fanout-exchange>

<topic-exchange name="app.stock.marketdata"
                xmlns="http://www.springframework.org/schema/rabbit">
    <bindings>
        <binding queue="marketDataQueue" pattern="${stocks.quote.pattern}"/>
    </bindings>
</topic-exchange>

在前面的例子中,我们使用匿名队列(实际上,在内部,只是由框架生成的名称的队列,而不是由代理生成的队列),并通过 ID 引用它们。 我们还可以声明具有显式名称的队列,这些名称也用作上下文中其 Bean 定义的标识符。 以下示例使用显式名称配置队列:Spring中文文档

<rabbit:queue name="stocks.trade.queue"/>
您可以同时提供 和 属性。 这允许您通过独立于队列名称的 ID 引用队列(例如,在绑定中)。 它还允许标准的 Spring 功能(例如队列名称的属性占位符和 SpEL 表达式)。 当您使用名称作为 Bean 标识符时,这些功能不可用。idname

可以使用其他参数配置队列,例如 . 使用命名空间支持时,它们以 argument-name/argument-value 对的形式提供,这些对是使用元素定义的。 以下示例演示如何执行此操作:x-message-ttlMap<rabbit:queue-arguments>Spring中文文档

<rabbit:queue name="withArguments">
    <rabbit:queue-arguments>
        <entry key="x-dead-letter-exchange" value="myDLX"/>
        <entry key="x-dead-letter-routing-key" value="dlqRK"/>
    </rabbit:queue-arguments>
</rabbit:queue>

默认情况下,假定参数为字符串。 对于其他类型的参数,必须提供类型。 下面的示例演示如何指定类型:Spring中文文档

<rabbit:queue name="withArguments">
    <rabbit:queue-arguments value-type="java.lang.Long">
        <entry key="x-message-ttl" value="100"/>
    </rabbit:queue-arguments>
</rabbit:queue>

提供混合类型的参数时,必须为每个条目元素提供类型。 以下示例演示如何执行此操作:Spring中文文档

<rabbit:queue name="withArguments">
    <rabbit:queue-arguments>
        <entry key="x-message-ttl">
            <value type="java.lang.Long">100</value>
        </entry>
        <entry key="x-dead-letter-exchange" value="myDLX"/>
        <entry key="x-dead-letter-routing-key" value="dlqRK"/>
    </rabbit:queue-arguments>
</rabbit:queue>

在 Spring Framework 3.2 及更高版本中,可以更简洁地声明这一点,如下所示:Spring中文文档

<rabbit:queue name="withArguments">
    <rabbit:queue-arguments>
        <entry key="x-message-ttl" value="100" value-type="java.lang.Long"/>
        <entry key="x-ha-policy" value="all"/>
    </rabbit:queue-arguments>
</rabbit:queue>

使用 Java 配置时,通过类上的方法支持将参数作为第一类属性。 从 V2.1 开始,默认情况下声明匿名队列时将此属性设置为。 这可确保在应用程序连接到的节点上声明队列。Queue.X_QUEUE_LEADER_LOCATORsetLeaderLocator()Queueclient-localSpring中文文档

RabbitMQ 代理不允许声明参数不匹配的队列。 例如,如果 a 已经存在且没有参数,并且您尝试用 (例如) 声明它,则会引发异常。queuetime to livekey="x-message-ttl" value="100"

默认情况下,当发生任何异常时,会立即停止处理所有声明。 这可能会导致下游问题,例如侦听器容器无法初始化,因为未声明另一个队列(在错误队列之后定义)。RabbitAdminSpring中文文档

可以通过将属性设置为 on the instance 来修改此行为。 此选项指示记录异常并继续声明其他元素。 配置使用 Java 时,此属性称为 。 这是应用于所有元素的全局设置。 队列、交换和绑定具有仅适用于这些元素的类似属性。ignore-declaration-exceptionstrueRabbitAdminRabbitAdminRabbitAdminignoreDeclarationExceptionsSpring中文文档

在版本 1.6 之前,仅当通道上发生此属性时,例如当前属性与所需属性不匹配时,此属性才会生效。 现在,此属性对任何异常(包括 和其他)生效。IOExceptionTimeoutExceptionSpring中文文档

此外,任何声明异常都会导致发布 ,该 是上下文中任何人都可以使用的 。 该事件包含对管理员、正在声明的元素和 .DeclarationExceptionEventApplicationEventApplicationListenerThrowableSpring中文文档

您可以同时提供 和 属性。 这允许您通过独立于队列名称的 ID 引用队列(例如,在绑定中)。 它还允许标准的 Spring 功能(例如队列名称的属性占位符和 SpEL 表达式)。 当您使用名称作为 Bean 标识符时,这些功能不可用。idname
RabbitMQ 代理不允许声明参数不匹配的队列。 例如,如果 a 已经存在且没有参数,并且您尝试用 (例如) 声明它,则会引发异常。queuetime to livekey="x-message-ttl" value="100"

标头交换

从版本 1.3 开始,您可以配置为在多个标头上匹配。 您还可以指定任何或所有标头是否必须匹配。 以下示例演示如何执行此操作:HeadersExchangeSpring中文文档

<rabbit:headers-exchange name="headers-test">
    <rabbit:bindings>
        <rabbit:binding queue="bucket">
            <rabbit:binding-arguments>
                <entry key="foo" value="bar"/>
                <entry key="baz" value="qux"/>
                <entry key="x-match" value="all"/>
            </rabbit:binding-arguments>
        </rabbit:binding>
    </rabbit:bindings>
</rabbit:headers-exchange>

从 V1.6 开始,您可以使用标志(默认为 )进行配置,并且通过 (如果应用程序上下文中存在一个标志)在 Broker 上正确配置。 如果该标志用于交换,则 RabbitMQ 不允许客户端使用该交换。 这对于死信交换或交换到交换绑定非常有用,在这种情况下,您不希望使用交换 直接由出版商提供。ExchangesinternalfalseExchangeRabbitAdmininternaltrueSpring中文文档

要了解如何使用 Java 配置 AMQP 基础结构,请查看 Stock 示例应用程序。 其中有类,而类又有 和 子类。 以下列表显示了以下代码:@ConfigurationAbstractStockRabbitConfigurationRabbitClientConfigurationRabbitServerConfigurationAbstractStockRabbitConfigurationSpring中文文档

@Configuration
public abstract class AbstractStockAppRabbitConfiguration {

    @Bean
    public CachingConnectionFactory connectionFactory() {
        CachingConnectionFactory connectionFactory =
            new CachingConnectionFactory("localhost");
        connectionFactory.setUsername("guest");
        connectionFactory.setPassword("guest");
        return connectionFactory;
    }

    @Bean
    public RabbitTemplate rabbitTemplate() {
        RabbitTemplate template = new RabbitTemplate(connectionFactory());
        template.setMessageConverter(jsonMessageConverter());
        configureRabbitTemplate(template);
        return template;
    }

    @Bean
    public Jackson2JsonMessageConverter jsonMessageConverter() {
        return new Jackson2JsonMessageConverter();
    }

    @Bean
    public TopicExchange marketDataExchange() {
        return new TopicExchange("app.stock.marketdata");
    }

    // additional code omitted for brevity

}

在 Stock 应用程序中,使用以下类配置服务器:@ConfigurationSpring中文文档

@Configuration
public class RabbitServerConfiguration extends AbstractStockAppRabbitConfiguration  {

    @Bean
    public Queue stockRequestQueue() {
        return new Queue("app.stock.request");
    }
}

这是整个类继承链的终点。 最终结果是 和 在应用程序启动时向代理声明。 在服务器配置中没有绑定到队列,因为这是在客户端应用程序中完成的。 但是,股票请求队列会自动绑定到 AMQP 默认交易所。 此行为由规范定义。@ConfigurationTopicExchangeQueueTopicExchangeSpring中文文档

客户端类更有趣一些。 其声明如下:@ConfigurationSpring中文文档

@Configuration
public class RabbitClientConfiguration extends AbstractStockAppRabbitConfiguration {

    @Value("${stocks.quote.pattern}")
    private String marketDataRoutingKey;

    @Bean
    public Queue marketDataQueue() {
        return amqpAdmin().declareQueue();
    }

    /**
     * Binds to the market data exchange.
     * Interested in any stock quotes
     * that match its routing key.
     */
    @Bean
    public Binding marketDataBinding() {
        return BindingBuilder.bind(
                marketDataQueue()).to(marketDataExchange()).with(marketDataRoutingKey);
    }

    // additional code omitted for brevity

}

客户端通过 . 它将该队列绑定到市场数据交换,并采用在属性文件中外部化的路由模式。declareQueue()AmqpAdminSpring中文文档

用于队列和 Exchange 的构建器 API

版本 1.6 引入了一个方便的 Fluent API,用于在使用 Java 配置时配置和对象。 以下示例演示如何使用它:QueueExchangeSpring中文文档

@Bean
public Queue queue() {
    return QueueBuilder.nonDurable("foo")
        .autoDelete()
        .exclusive()
        .withArgument("foo", "bar")
        .build();
}

@Bean
public Exchange exchange() {
  return ExchangeBuilder.directExchange("foo")
      .autoDelete()
      .internal()
      .withArgument("foo", "bar")
      .build();
}

从 2.0 版开始,现在默认创建持久交换,以便与各个类上的简单构造函数保持一致。 要与构建器进行非持久交换,请在调用之前使用 。 不再提供不带参数的方法。ExchangeBuilderAbstractExchange.durable(false).build()durable()Spring中文文档

版本 2.2 引入了流畅的 API,以添加“众所周知的”交换和队列参数......Spring中文文档

@Bean
public Queue allArgs1() {
    return QueueBuilder.nonDurable("all.args.1")
            .ttl(1000)
            .expires(200_000)
            .maxLength(42)
            .maxLengthBytes(10_000)
            .overflow(Overflow.rejectPublish)
            .deadLetterExchange("dlx")
            .deadLetterRoutingKey("dlrk")
            .maxPriority(4)
            .lazy()
            .leaderLocator(LeaderLocator.minLeaders)
            .singleActiveConsumer()
            .build();
}

@Bean
public DirectExchange ex() {
    return ExchangeBuilder.directExchange("ex.with.alternate")
            .durable(true)
            .alternate("alternate")
            .build();
}

声明 Exchange、Queue 和 Bindings 的集合

可以将对象 (、 和 ) 的集合包装在对象中。 在应用程序上下文中检测此类 Bean(以及离散 Bean),并在建立连接时(最初和连接失败后)声明代理上包含的对象。 以下示例演示如何执行此操作:DeclarableQueueExchangeBindingDeclarablesRabbitAdminDeclarableSpring中文文档

@Configuration
public static class Config {

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

    @Bean
    public RabbitAdmin admin(ConnectionFactory cf) {
        return new RabbitAdmin(cf);
    }

    @Bean
    public DirectExchange e1() {
        return new DirectExchange("e1", false, true);
    }

    @Bean
    public Queue q1() {
        return new Queue("q1", false, false, true);
    }

    @Bean
    public Binding b1() {
        return BindingBuilder.bind(q1()).to(e1()).with("k1");
    }

    @Bean
    public Declarables es() {
        return new Declarables(
                new DirectExchange("e2", false, true),
                new DirectExchange("e3", false, true));
    }

    @Bean
    public Declarables qs() {
        return new Declarables(
                new Queue("q2", false, false, true),
                new Queue("q3", false, false, true));
    }

    @Bean
    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    public Declarables prototypes() {
        return new Declarables(new Queue(this.prototypeQueueName, false, false, true));
    }

    @Bean
    public Declarables bs() {
        return new Declarables(
                new Binding("q2", DestinationType.QUEUE, "e2", "k2", null),
                new Binding("q3", DestinationType.QUEUE, "e3", "k3", null));
    }

    @Bean
    public Declarables ds() {
        return new Declarables(
                new DirectExchange("e4", false, true),
                new Queue("q4", false, false, true),
                new Binding("q4", DestinationType.QUEUE, "e4", "k4", null));
    }

}
在 2.1 之前的版本中,您可以通过定义 类型的 bean 来声明多个实例。 在某些情况下,这可能会导致不良副作用,因为管理员必须遍历所有 bean。DeclarableCollection<Declarable>Collection<?>

版本 2.2 将该方法添加到 ;这可以用作方便,例如,在声明侦听器容器 Bean 时。getDeclarablesByTypeDeclarablesSpring中文文档

public SimpleMessageListenerContainer container(ConnectionFactory connectionFactory,
        Declarables mixedDeclarables, MessageListener listener) {

    SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory);
    container.setQueues(mixedDeclarables.getDeclarablesByType(Queue.class).toArray(new Queue[0]));
    container.setMessageListener(listener);
    return container;
}
在 2.1 之前的版本中,您可以通过定义 类型的 bean 来声明多个实例。 在某些情况下,这可能会导致不良副作用,因为管理员必须遍历所有 bean。DeclarableCollection<Declarable>Collection<?>

有条件声明

默认情况下,所有队列、交换和绑定都由应用程序上下文中的所有实例声明(假设它们有 )。RabbitAdminauto-startup="true"Spring中文文档

从版本 2.1.9 开始,具有一个新属性(默认情况下);当此值设置为 时,管理员将仅声明显式配置为由该管理员声明的 Bean。RabbitAdminexplicitDeclarationsOnlyfalsetrueSpring中文文档

从 1.2 版本开始,您可以有条件地声明这些元素。 当应用程序连接到多个代理并需要指定应向哪些代理声明特定元素时,这特别有用。

表示这些元素的类实现 ,它有两个方法:和 。 使用这些方法确定特定实例是否应实际处理其 .DeclarableshouldDeclare()getDeclaringAdmins()RabbitAdminConnectionSpring中文文档

这些属性在命名空间中用作属性,如以下示例所示:Spring中文文档

<rabbit:admin id="admin1" connection-factory="CF1" />

<rabbit:admin id="admin2" connection-factory="CF2" />

<rabbit:admin id="admin3" connection-factory="CF3" explicit-declarations-only="true" />

<rabbit:queue id="declaredByAdmin1AndAdmin2Implicitly" />

<rabbit:queue id="declaredByAdmin1AndAdmin2" declared-by="admin1, admin2" />

<rabbit:queue id="declaredByAdmin1Only" declared-by="admin1" />

<rabbit:queue id="notDeclaredByAllExceptAdmin3" auto-declare="false" />

<rabbit:direct-exchange name="direct" declared-by="admin1, admin2">
    <rabbit:bindings>
        <rabbit:binding key="foo" queue="bar"/>
    </rabbit:bindings>
</rabbit:direct-exchange>
默认情况下,属性为 and,如果未提供(或为空),则所有实例都声明对象(只要 admin 的属性为 ,默认值,并且 admin 的属性为 false)。auto-declaretruedeclared-byRabbitAdminauto-startuptrueexplicit-declarations-only

同样,您可以使用基于 Java 的来实现相同的效果。 在以下示例中,组件由 声明,但不是由:@Configurationadmin1admin2Spring中文文档

@Bean
public RabbitAdmin admin1() {
    return new RabbitAdmin(cf1());
}

@Bean
public RabbitAdmin admin2() {
    return new RabbitAdmin(cf2());
}

@Bean
public Queue queue() {
    Queue queue = new Queue("foo");
    queue.setAdminsThatShouldDeclare(admin1());
    return queue;
}

@Bean
public Exchange exchange() {
    DirectExchange exchange = new DirectExchange("bar");
    exchange.setAdminsThatShouldDeclare(admin1());
    return exchange;
}

@Bean
public Binding binding() {
    Binding binding = new Binding("foo", DestinationType.QUEUE, exchange().getName(), "foo", null);
    binding.setAdminsThatShouldDeclare(admin1());
    return binding;
}
从 1.2 版本开始,您可以有条件地声明这些元素。 当应用程序连接到多个代理并需要指定应向哪些代理声明特定元素时,这特别有用。
默认情况下,属性为 and,如果未提供(或为空),则所有实例都声明对象(只要 admin 的属性为 ,默认值,并且 admin 的属性为 false)。auto-declaretruedeclared-byRabbitAdminauto-startuptrueexplicit-declarations-only

关于 和 属性的说明idname

属性 on 和 elements 反映代理中实体的名称。 对于队列,如果省略 ,则会创建一个匿名队列(请参阅 AnonymousQueue)。name<rabbit:queue/><rabbit:exchange/>nameSpring中文文档

在 2.0 之前的版本中,还注册为 Bean 名称别名(类似于 on 元素)。namename<bean/>Spring中文文档

这导致了两个问题:Spring中文文档

从 V2.0 开始,如果声明其中一个元素同时具有 an 和 a 属性,那么该名称将不再声明为 Bean 名称别名。 如果您希望声明一个队列并与该队列交换,则必须提供 .idnamenameidSpring中文文档

如果元素只有一个属性,则没有变化。 Bean 仍可由 — 引用,例如,在绑定声明中。 但是,如果名称包含 SpEL,则仍然无法引用它 - 您必须提供 以供参考。namenameidSpring中文文档

AnonymousQueue

通常,当您需要唯一命名的独占自动删除队列时,我们建议您使用 而不是代理定义的队列名称(用作名称会导致代理生成队列 名称)。AnonymousQueue""QueueSpring中文文档

这是因为:Spring中文文档

  1. 队列实际上是在建立与代理的连接时声明的。 这是在 Bean 被创建并连接在一起之后很久。 使用队列的 Bean 需要知道它的名称。 事实上,当应用程序启动时,代理甚至可能没有运行。Spring中文文档

  2. 如果由于某种原因与代理的连接丢失,管理员将重新声明具有相同的名称。 如果我们使用代理声明的队列,队列名称将更改。AnonymousQueueSpring中文文档

您可以控制实例使用的队列名称的格式。AnonymousQueueSpring中文文档

默认情况下,队列名称的前缀为 后跟 base64 表示形式,例如:.spring.gen-UUIDspring.gen-MRBv9sqISkuCiPfOYfpo4gSpring中文文档

可以在构造函数参数中提供实现。 以下示例演示如何执行此操作:AnonymousQueue.NamingStrategySpring中文文档

@Bean
public Queue anon1() {
    return new AnonymousQueue();
}

@Bean
public Queue anon2() {
    return new AnonymousQueue(new AnonymousQueue.Base64UrlNamingStrategy("something-"));
}

@Bean
public Queue anon3() {
    return new AnonymousQueue(AnonymousQueue.UUIDNamingStrategy.DEFAULT);
}

第一个 Bean 生成一个队列名称,前缀为 前缀,后跟 — for 的 base64 表示形式。 例:。 第二个 Bean 生成一个队列名称,前缀为 后跟 的 base64 表示形式。 第三个 Bean 仅使用 UUID(无 base64 转换)生成名称,例如 .spring.gen-UUIDspring.gen-MRBv9sqISkuCiPfOYfpo4gsomething-UUIDf20c818a-006b-4416-bf91-643590fedb0eSpring中文文档

base64 编码使用 RFC 4648 中的“URL 和文件名安全字母表”。 删除了尾随填充字符 ()。=Spring中文文档

您可以提供自己的命名策略,从而可以在队列名称中包含其他信息(例如应用程序名称或客户端主机)。Spring中文文档

您可以在使用 XML 配置时指定命名策略。 该属性存在于元素上 对于实现 的 Bean 引用。 以下示例演示如何以各种方式指定命名策略:naming-strategy<rabbit:queue>AnonymousQueue.NamingStrategySpring中文文档

<rabbit:queue id="uuidAnon" />

<rabbit:queue id="springAnon" naming-strategy="uuidNamer" />

<rabbit:queue id="customAnon" naming-strategy="customNamer" />

<bean id="uuidNamer" class="org.springframework.amqp.core.AnonymousQueue.UUIDNamingStrategy" />

<bean id="customNamer" class="org.springframework.amqp.core.AnonymousQueue.Base64UrlNamingStrategy">
    <constructor-arg value="custom.gen-" />
</bean>

第一个示例创建诸如 . 第二个示例使用 UUID 的 String 表示形式创建名称。 第三个示例创建诸如 .spring.gen-MRBv9sqISkuCiPfOYfpo4gcustom.gen-MRBv9sqISkuCiPfOYfpo4gSpring中文文档

您还可以提供自己的命名策略 bean。Spring中文文档

从版本 2.1 开始,默认情况下声明匿名队列的参数设置为。 这可确保在应用程序连接到的节点上声明队列。 您可以在构造实例后通过调用来恢复到以前的行为。Queue.X_QUEUE_LEADER_LOCATORclient-localqueue.setLeaderLocator(null)Spring中文文档

恢复自动删除声明

通常,(s) 只恢复在应用程序上下文中声明为 Bean 的队列/交换/绑定;如果任何此类声明是自动删除的,那么如果连接丢失,代理将删除它们。 重新建立连接后,管理员将重新声明实体。 通常,通过调用创建的实体不会被恢复。RabbitAdminadmin.declareQueue(…​)admin.declareExchange(…​)admin.declareBinding(…​)Spring中文文档

从版本 2.4 开始,管理员有一个新属性;当 时,管理员将恢复这些实体以及应用程序上下文中的 Bean。redeclareManualDeclarationstrueSpring中文文档

如果调用了 或,则不会执行单个声明的恢复。 删除队列和交换时,将从可恢复实体中删除关联的绑定。deleteQueue(…​)deleteExchange(…​)removeBinding(…​)Spring中文文档

最后,调用将阻止恢复任何先前声明的实体。resetAllManualDeclarations()Spring中文文档