返回介绍

17.3.4 接收 AMQP 消息

发布于 2024-08-17 00:45:49 字数 3236 浏览 0 评论 0 收藏 0

我们可以回忆一下,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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文