此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring AMQP 3.2.0spring-doc.cadn.net.cn

AMQP 抽象

Spring AMQP 由两个模块组成(每个模块由发行版中的一个 JAR 表示):spring-amqpspring-rabbit. 'spring-amqp' 模块包含org.springframework.amqp.core包。 在该包中,您可以找到表示核心 AMQP“模型”的类。 我们的目的是提供不依赖于任何特定 AMQP 代理实现或客户端库的通用抽象。 最终用户代码可以跨供应商实现更具可移植性,因为它只能针对抽象层进行开发。 然后,这些抽象由特定于 broker 的模块(例如'spring-rabbit')实现。 目前只有一个 RabbitMQ 实现。 但是,除了 RabbitMQ 之外,还使用 Apache Qpid 在 .NET 中验证了抽象。 由于 AMQP 在协议级别运行,原则上,您可以将 RabbitMQ 客户端与任何支持相同协议版本的代理一起使用,但我们目前不测试任何其他代理。spring-doc.cadn.net.cn

本概述假定您已经熟悉 AMQP 规范的基础知识。 如果没有,请查看 Other Resources 中列出的资源spring-doc.cadn.net.cn

Message

0-9-1 AMQP 规范没有定义Message类或接口。 相反,当执行basicPublish(),内容作为字节数组参数传递,其他属性作为单独的参数传入。 Spring AMQP 定义了一个Message类作为更通用的 AMQP 域模型表示的一部分。 目的Messageclass 将 body 和 properties 封装在单个实例中,以便 API 反过来可以更简单。 以下示例显示了Message类定义:spring-doc.cadn.net.cn

public class Message {

    private final MessageProperties messageProperties;

    private final byte[] body;

    public Message(byte[] body, MessageProperties messageProperties) {
        this.body = body;
        this.messageProperties = messageProperties;
    }

    public byte[] getBody() {
        return this.body;
    }

    public MessageProperties getMessageProperties() {
        return this.messageProperties;
    }
}

MessagePropertiesinterface 定义了几个常见的属性,比如 'messageId'、'timestamp'、'contentType' 等等。 您还可以通过调用setHeader(String key, Object value)方法。spring-doc.cadn.net.cn

从版本开始1.5.7,1.6.11,1.7.42.0.0,如果消息正文是序列化的Serializablejava 对象,则在执行toString()作(例如在日志消息中)。 这是为了防止不安全的反序列化。 默认情况下,只有java.utiljava.lang类被反序列化。 要恢复到之前的行为,您可以通过调用Message.addAllowedListPatterns(…​). 例如,支持简单的通配符*com.something.*, *.MyClass. 无法反序列化的主体由byte[<size>]在日志消息中。

交换

Exchangeinterface 表示 AMQP Exchange,这是 Message Producer 发送到的目标。 代理的虚拟主机中的每个 Exchange 都有一个唯一的名称以及一些其他属性。 以下示例显示了Exchange接口:spring-doc.cadn.net.cn

public interface Exchange {

    String getName();

    String getExchangeType();

    boolean isDurable();

    boolean isAutoDelete();

    Map<String, Object> getArguments();

}

如您所见,Exchange还有一个 'type' 由 中定义的常量表示ExchangeTypes. 基本类型包括:direct,topic,fanoutheaders. 在 core 包中,您可以找到Exchange接口。 这些Exchange类型。 例如,Directexchange 允许队列由固定的路由键(通常是队列的名称)绑定。 一个TopicExchange 支持具有路由模式的绑定,这些模式可能包括分别表示“Exactly One”和“Zero-or-More”的“*”和“#”通配符。 这FanoutExchange 发布到绑定到它的所有队列,而不考虑任何路由键。 有关这些类型和其他 Exchange 类型的更多信息,请参阅 AMQP Exchangesspring-doc.cadn.net.cn

从版本 3.2 开始,ConsistentHashExchange为方便起见,在应用程序配置阶段引入了 type。 它提供了以下选项x-consistent-hash对于 Exchange 类型。 允许配置hash-headerhash-propertyexchange definition 参数。 相应的 RabbitMQrabbitmq_consistent_hash_exchangeplugin 必须在 broker 上启用。 有关一致哈希交换的用途、逻辑和行为的更多信息,请参阅官方 RabbitMQ 文档spring-doc.cadn.net.cn

AMQP 规范还要求任何代理提供没有名称的 “默认” 直接交换。 声明的所有队列都绑定到该默认值Exchange,其名称作为路由键。 您可以在 Spring AMQP 中了解有关默认 Exchange 用法的更多信息,请参阅AmqpTemplate.

队列

Queueclass 表示消息使用者从中接收消息的组件。 像各种Exchange类,我们的实现旨在成为这个核心 AMQP 类型的抽象表示。 下面的清单显示了Queue类:spring-doc.cadn.net.cn

public class Queue  {

    private final String name;

    private volatile boolean durable;

    private volatile boolean exclusive;

    private volatile boolean autoDelete;

    private volatile Map<String, Object> arguments;

    /**
     * The queue is durable, non-exclusive and non auto-delete.
     *
     * @param name the name of the queue.
     */
    public Queue(String name) {
        this(name, true, false, false);
    }

    // Getters and Setters omitted for brevity

}

请注意,构造函数采用队列名称。 根据实现, admin 模板可能会提供生成唯一命名队列的方法。 此类队列可用作 “reply-to” 地址或其他临时情况。 因此,自动生成的队列的 'exclusive' 和 'autoDelete' 属性都将设置为 'true'。spring-doc.cadn.net.cn

有关使用命名空间支持(包括队列参数)声明队列的信息,请参阅配置 Broker 中有关队列的部分。

捆绑

鉴于生产者向交换发送数据,而使用者从队列接收数据,则将队列连接到交换的绑定对于通过消息收发连接这些生产者和使用者至关重要。 在 Spring AMQP 中,我们定义了一个Binding类来表示这些连接。 本节回顾将队列绑定到 exchanges 的基本选项。spring-doc.cadn.net.cn

您可以将队列绑定到DirectExchange使用固定的路由密钥,如下例所示:spring-doc.cadn.net.cn

new Binding(someQueue, someDirectExchange, "foo.bar");

您可以将队列绑定到TopicExchange使用路由模式,如下例所示:spring-doc.cadn.net.cn

new Binding(someQueue, someTopicExchange, "foo.*");

您可以将队列绑定到FanoutExchange没有路由密钥,如下例所示:spring-doc.cadn.net.cn

new Binding(someQueue, someFanoutExchange);

我们还提供BindingBuilder促进“Fluent API”样式,如下例所示:spring-doc.cadn.net.cn

Binding b = BindingBuilder.bind(someQueue).to(someTopicExchange).with("foo.*");
为清楚起见,前面的示例显示了BindingBuilder类,但这种样式在对 'bind()' 方法使用静态导入时效果很好。

就其本身而言,这个Bindingclass 仅保存有关 connection 的数据。 换句话说,它不是一个 “active” 组件。 但是,正如您稍后将在 配置 Broker 中看到的那样,AmqpAdmin类可以使用Binding实例来实际触发 broker 上的绑定作。 此外,正如您在同一部分中所看到的,您可以定义Binding实例使用 Spring 的@Beanannotations 中的@Configuration类。 还有一个方便的基类,它进一步简化了生成与 AMQP 相关的 bean 定义的方法,并识别队列、交换和绑定,以便在应用程序启动时在 AMQP 代理上声明它们。spring-doc.cadn.net.cn

AmqpTemplate也在 core 包中定义。 作为实际 AMQP 消息传递中涉及的主要组件之一,它在其自己的部分中进行了详细讨论(参见AmqpTemplate).spring-doc.cadn.net.cn