ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
[toc] ## 介绍 Spring AMQP由一些模块组成,每个模块由发布中的JAR表示。 这些模块是:spring-amqp和spring-rabbit。 spring-amqp模块包含`org.springframework.amqp.core`包。 在该包中,您将找到代表核心AMQP“模型”的类。 我们的目的是提供不依赖于任何特定AMQP代理实现或客户端库的通用抽象。 最终用户代码在供应商实现中更具可移植性,因为它只能针对抽象层进行开发。 然后使用这些抽象由特定于代理的模块实现,例如spring-rabbit。 目前只有RabbitMQ实现; 但是,除了RabbitMQ之外,还使用Apache Qpid在.NET中验证了抽象。 由于AMQP原则上在协议级别运行,因此RabbitMQ客户端可以与支持相同协议版本的任何代理一起使用,但我们目前不测试任何其他代理。 此处概述假定您已熟悉AMQP规范的基础知识。 如果不是,请查看第5章“其他资源”中列出的资源 ## 消息 0-9-1 AMQP规范未定义Message类或接口。 替代的,当执行诸如`basicPublish()`之类的操作时,内容将作为字节数组参数传递,并且其他属性将作为单独的参数传递。 Spring AMQP将Message类定义为更通用的AMQP域模型表示的一部分。 Message类的目的是简单地将主体和属性封装在单个实例中,以便API可以更简单。 Message类定义非常简单。 ~~~java 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; } } ~~~ `MessageProperties`接口定义了几个常见属性,例如`messageId`,`timestamp`,`contentType`等等。 通过调用`setHeader(String key, Object value)`方法,还可以自定义扩展这些属性。 ## 交换机 接口`Exchange `代表AMQP 的交换机,就是消息生产者要发送的地方. 代理虚拟主机中的每个交换机都具有唯一的名称以及一些其他属性: ~~~java public interface Exchange { String getName(); String getExchangeType(); boolean isDurable(); boolean isAutoDelete(); Map<String, Object> getArguments(); } ~~~ 如您所见,`Exchange`还具有由`ExchangeTypes`中定义的常量表示的类型。 基本类型包括:`Direct`,`Topic`,`Fanout`和`Headers`。 在核心包中,您将找到每种类型的Exchange接口的实现。 在这些Exchange类型处理绑定到队列的方式方面,行为会有所不同。 例如,直连交换机允许队列由固定路由键(通常是队列的名称)绑定。 主题交换机支持具有路由模式的绑定,路由模式可以分别包括*和#通配符,分别用于一个和零或多个。 扇型交换机发布消息到绑定到它的所有队列,而不考虑任何路由键。 有关这些和其他Exchange类型的更多信息,请参阅第5章,其他资源。 ## 队列 `Queue`类表示消息使用者从中接收消息的组件。 与各种Exchange类一样,我们的实现旨在成为此核心AMQP类型的抽象表示。 ~~~java 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; /** * 队列是持久的,非独占的和非自动删除。 * * @param name the name of the queue. */ public Queue(String name) { this(name, true, false, false); } // Getters and Setters omitted for brevity } ~~~ 请注意,构造函数采用队列名称。 根据实现,管理模板可以提供用于生成唯一命名的队列的方法。 此类队列可用作“回复”地址或其他临时情况。 因此,自动生成的Queue的exclusive和autoDelete属性都将设置为true。 ## 绑定 鉴于生产者发送到Exchange并且消费者从队列接收,将队列连接到Exchange的绑定对于通过消息传递连接这些生产者和消费者是至关重要的。 在Spring AMQP中,我们定义了一个Binding类来表示这些连接。 让我们回顾一下将队列绑定到Exchange的基本选项。 您可以使用固定的路由键将队列绑定到DirectExchange。 ~~~java new Binding(someQueue, someDirectExchange, "foo.bar") ~~~ 您可以使用路由模式将队列绑定到TopicExchange。 ~~~ new Binding(someQueue, someTopicExchange, "foo.*") ~~~ 您可以将队列绑定到没有路由键的FanoutExchange。 ~~~ new Binding(someQueue, someFanoutExchange) ~~~ 我们还提供了一个`BindingBuilder`来促进“流畅的API”风格。 ~~~ Binding b = BindingBuilder.bind(someQueue).to(someTopicExchange).with("foo.*"); ~~~ 就其本身而言,Binding类的一个实例只是保存有关连接的数据。 换句话说,它不是“活动”组件。 但是,正如您将在后面的第3.1.10节“配置代理”中看到的那样,`AmqpAdmin`类可以使用绑定实例来实际触发代理上的绑定操作。 另外,正如您将在同一部分中看到的那样,可以使用`@Configuration`类中的Spring的`@Bean`样式定义Binding实例。 还有一个方便的基类,它进一步简化了生成与AMQP相关的bean定义并识别队列,交换和绑定的方法,以便在应用程序启动时它们都将在AMQP代理上声明。 `AmqpTemplate`也在核心包中定义。 作为实际AMQP消息传递中涉及的主要组件之一,它将在其自己的部分中详细讨论(请参见第3.1.4节“AmqpTemplate”)。