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

本概述假定您已经熟悉 AMQP 规范的基础知识。 如果没有,请查看其他资源中列出的资源Spring中文文档

Message

0-9-1 AMQP 规范未定义类或接口。 相反,在执行诸如 之类的操作时,内容将作为字节数组参数传递,而其他属性将作为单独的参数传入。 Spring AMQP 将类定义为更通用的 AMQP 域模型表示的一部分。 该类的目的是将主体和属性封装在单个实例中,以便 API 可以更简单。 下面的示例演示了类定义:MessagebasicPublish()MessageMessageMessageSpring中文文档

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;
    }
}

该接口定义了几个常见属性,例如“messageId”、“timestamp”、“contentType”等。 还可以通过调用该方法使用用户定义的“标头”扩展这些属性。MessagePropertiessetHeader(String key, Object value)Spring中文文档

从版本 、 、 和 开始,如果消息正文是序列化的 java 对象,那么在执行操作(例如在日志消息中)时,它不再被反序列化(默认情况下)。 这是为了防止不安全的反序列化。 默认情况下,只有 和 类是反序列化的。 要恢复到以前的行为,可以通过调用 来添加允许的类/包模式。 支持简单的通配符,例如 com.something.。 无法反序列化的正文由 in 日志消息表示。1.5.71.6.111.7.42.0.0SerializabletoString()java.utiljava.langMessage.addAllowedListPatterns(…​), *.MyClassbyte[<size>]
从版本 、 、 和 开始,如果消息正文是序列化的 java 对象,那么在执行操作(例如在日志消息中)时,它不再被反序列化(默认情况下)。 这是为了防止不安全的反序列化。 默认情况下,只有 和 类是反序列化的。 要恢复到以前的行为,可以通过调用 来添加允许的类/包模式。 支持简单的通配符,例如 com.something.。 无法反序列化的正文由 in 日志消息表示。1.5.71.6.111.7.42.0.0SerializabletoString()java.utiljava.langMessage.addAllowedListPatterns(…​), *.MyClassbyte[<size>]

交换

该接口表示 AMQP Exchange,这是消息生产者发送到的内容。 代理虚拟主机中的每个 Exchange 都具有唯一的名称以及一些其他属性。 以下示例显示了该接口:ExchangeExchangeSpring中文文档

public interface Exchange {

    String getName();

    String getExchangeType();

    boolean isDurable();

    boolean isAutoDelete();

    Map<String, Object> getArguments();

}

正如你所看到的,an 还有一个“类型”,由 中定义的常量表示。 基本类型有:、、 和 。 在核心包中,您可以找到每种类型的接口实现。 这些类型的行为在处理队列绑定的方式方面有所不同。 例如,交换允许队列由固定路由键(通常是队列的名称)绑定。 交换支持具有路由模式的绑定,这些模式可能分别包含“exactly-one”和“0-or-more”的“*”和“#”通配符。 交换发布到绑定到它的所有队列,而不考虑任何路由密钥。 有关这些类型和其他 Exchange 类型的详细信息,请参阅其他资源ExchangeExchangeTypesdirecttopicfanoutheadersExchangeExchangeDirectTopicFanoutSpring中文文档

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

队列

该类表示消息使用者从中接收消息的组件。 与各种类一样,我们的实现旨在成为此核心 AMQP 类型的抽象表示。 以下列表显示了该类:QueueExchangeQueueSpring中文文档

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

}

请注意,构造函数采用队列名称。 根据实现的不同,管理模板可能会提供用于生成唯一命名队列的方法。 此类队列可用作“回复”地址或其他临时情况。 因此,自动生成的队列的“exclusive”和“autoDelete”属性都将设置为“true”。Spring中文文档

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

捆绑

鉴于生产者向交易所发送消息,而使用者从队列接收,则将队列连接到交易所的绑定对于通过消息传递连接这些生产者和使用者至关重要。 在 Spring AMQP 中,我们定义了一个类来表示这些连接。 本节介绍将队列绑定到交易所的基本选项。BindingSpring中文文档

您可以使用固定路由键将队列绑定到队列,如以下示例所示:DirectExchangeSpring中文文档

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

您可以使用路由模式将队列绑定到队列,如以下示例所示:TopicExchangeSpring中文文档

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

您可以将队列绑定到没有路由键的队列,如以下示例所示:FanoutExchangeSpring中文文档

new Binding(someQueue, someFanoutExchange);

我们还提供了一个促进“流畅 API”样式,如以下示例所示:BindingBuilderSpring中文文档

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

就其本身而言,类的实例仅保存有关连接的数据。 换句话说,它不是一个“活动”组件。 但是,正如您稍后将在配置代理中看到的那样,该类可以使用实例来实际触发代理上的绑定操作。 此外,正如您在同一部分中看到的,您可以通过在类中使用 Spring 的注解来定义实例。 还有一个方便的基类,它进一步简化了生成 AMQP 相关 Bean 定义的方法,并识别队列、交换和绑定,以便在应用程序启动时在 AMQP 代理上声明它们。BindingAmqpAdminBindingBinding@Bean@ConfigurationSpring中文文档

也在核心包中定义。 作为实际 AMQP 消息传递中涉及的主要组件之一,它在自己的部分中进行了详细讨论(请参阅 AmqpTemplate)。AmqpTemplateSpring中文文档

为清楚起见,前面的示例显示了该类,但是当对“bind()”方法使用静态导入时,这种样式效果很好。BindingBuilder