- 作者简介
- 内容提要
- 关于本书
- 路线图
- 代码规范与下载
- 作者在线
- 封面插图简介
- 前言
- 译者序
- 致谢
- 第1部分 Spring 的核心
- 第1章 Spring 之旅
- 第2章 装配 Bean
- 第3章 高级装配
- 第4章 面向切面的 Spring
- 第2部分 Web 中的 Spring
- 第5章 构建 Spring Web 应用程序
- 第6章 渲染 Web 视图
- 第7章 Spring MVC 的高级技术
- 第8章 使用 Spring Web Flow
- 第9章 保护 Web 应用
- 第3部分 后端中的 Spring
- 第10章 通过 Spring 和 JDBC 征服数据库
- 第11章 使用对象-关系映射持久化数据
- 第12章 使用 NoSQL 数据库
- 第13章 缓存数据
- 第14章 保护方法应用
- 第4部分 Spring 集成
- 第15章 使用远程服务
- 第16章 使用 Spring MVC 创建 REST API
- 第17章 Spring消息
- 第18章 使用 WebSocket 和 STOMP 实现消息功能
- 第19章 使用 Spring 发送 Email
- 第20章 使用 JMX 管理 Spring Bean
- 第21章 借助 Spring Boot 简化 Spring 开发
17.3.4 接收 AMQP 消息
我们可以回忆一下,JMS提供了两种从队列中获取信息的方式:使用JmsTemplate的同步方式以及使用消息驱动POJO的异步方式。Spring AMQP提供了类似的方式来获取通过AMQP发送的消息。因为我们已经有了RabbitTemplate,所以首先看一下如何使用它同步地从队列中获取消息。
使用RabbitTemplate来接收消息
RabbitTemplate提供了多个接收信息的方法。最简单就是receive()方法,它位于消息的消费者端,对应于RabbitTemplate的send()方法。借助receive()方法,我们可以从队列中获取一个Message对象:
或者,如果愿意的话,你还可以配置获取消息的默认队列,这是通过在配置模板的时候,设置queue属性实现的:
这样的话,我们在调用receive()方法的时候,不需要设置任何参数就能从默认队列中获取消息了:
在获取到Message对象之后,我们可能需要将它body属性中的字节数组转换为想要的对象。就像在发送的时候将领域对象转换为Message一样,将接收到的Message转换为领域对象同样非常繁琐。因此,我们可以考虑使用RabbitTemplate的receiveAndConvert()方法作为替代方案:
我们还可以省略调用参数中的队列名称,这样它就会使用模板的默认队列名称:
receiveAndConvert()方法会使用与sendAndConvert()方法相同的消息转换器,将Message对象转换为原始的类型。
调用receive()和receiveAndConvert()方法都会立即返回,如果队列中没有等待的消息时,将会得到null。这就需要我们来管理轮询(polling)以及必要的线程,实现队列的监控。
我们并非必须同步轮询并等待消息到达,Spring AMQP还提供了消息驱动POJO的支持,这不禁使我们回忆起Spring JMS中的相同特性。让我们看一下如何通过消息驱动AMQP POJO的方式来接收消息。
定义消息驱动的AMQP POJO
如果你想在消息驱动POJO中异步地消费使用Spittle对象,首先要解决的问题就是这个POJO本身。如下的SpittleAlertHandler扮演了这个角色:
注意,这个类与借助JMS消费Spittle时所用到SpittleAlertHandler完全一致。我们之所以能够重用相同的POJO是因为这个类丝毫没有依赖于JMS或AMQP,并且不管通过什么机制传递过来Spittle对象,它都能够进行处理。
我们还需要在Spring应用上下文中将SpittleAlertHandler声明为一个bean:
同样,在使用基于JMS的MDP时,我们已经做过相同的事情,没有什么丝毫的差异。
最后,我们需要声明一个监听器容器和监听器,当消息到达的时候,能够调用SpittleAlertHandler。在基于JMS的MDP中,我们做过相同的事情,但是基于AMQP的MDP在配置上有一个细微的差别:
你看到有什么差别了吗?我也同意这并不那么明显。<listener-container>与<listener>都与JMS对应的元素非常类似。但是,这些元素来自rabbit命名空间,而不是JMS命名空间。
我都说过了,没那么明显。
哦,还有一个细微的差别,我们不再通过destination属性(JMS中的做法)来监听队列或主题,这里我们通过queue-names属性来指定要监听的队列。但是,除此之外,基于AMQP的MDP与基于JMS的MDP都非常类似。
你可能也意识到了,queue-names属性的名称使用了复数形式。在这里我们只设定了一个要监听的队列,但是允许设置多个队列的名称,用逗号分割即可。
另外一种指定要监听队列的方法是引用<queue>元素所声明的队列bean。我们可以通过queues属性来进行设置:
同样,这里可以接受逗号分割的queue ID列表。当然,这需要我们在声明队列的时候,为其指定ID。例如,如下是重新定义的提醒队列,这次指定了ID:
注意,这里的id属性用来在Spring应用上下文中设置队列的bean ID,而name属性指定了RabbitMQ代理中队列的名称。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论