17.2.1 在 Spring 中搭建消息代理

ActiveMQ 是一个伟大的开源消息代理产品,也是使用 JMS 进行异步消息传递的最佳选择。在我编写本书的时候,ActiveMQ 的最新版本为 5.9.1。在开始使用 ActiveMQ 之前,我们需要从 http://activemq.apache.org下载二进制发行包。下载完 ActiveMQ 后,我们将其解压缩到本地硬盘中。在解压目录中,我们会找到文件 activemq-core-5.9.1.jar。为了能够使用 ActiveMQ 的 API,我们需要将此 JAR 文件添加到应用程序的类路径中。

在 bin 目录下,我们可以看到为各种操作系统所创建的对应子目录。在这些子目录下,我们可以找到用于启动 ActiveMQ 的脚本。例如,要在 OS X 下启动 ActiveMQ,我们只需要在 “bin/macosx” 目录下运行 activemq start。运行脚本后,ActiveMQ 就准备好了,这时可以使用它作为消息代理。

创建连接工厂

在本章中,我们将了解如何采用不同的方式在 Spring 中使用 JMS 发送和接收消息。在所有的示例中,我们都需要借助 JMS 连接工厂通过消息代理发送消息。因为选择了 ActiveMQ 作为我们的消息代理,所以我们必须配置 JMS 连接工厂,让它知道如何连接到 ActiveMQ。ActiveMQConnectionFactory 是 ActiveMQ 自带的连接工厂,在 Spring 中可以使用如下方式进行配置:

<bean id="connectionFactory"
      class="org.apache.activemq.spring.ActiveMQConnectionFactory" />

默认情况下,ActiveMQConnectionFactory 会假设 ActiveMQ 代理监听 localhost 的 61616 端口。对于开发环境来说,这没有什么问题,但是在生产环境下,ActiveMQ 可能会在不同的主机和/端口上。如果是这样的话,我们可以使用 brokerURL 属性来指定代理的 URL:

<bean id="connectionFactory"
      class="org.apache.activemq.spring.ActiveMQConnectionFactory"
      p:brokerURL="tcp://localhost:61616" />

配置连接工厂还有另外一种方式,既然我们知道正在与 ActiveMQ 打交道,那我们就可以使用 ActiveMQ 自己的 Spring 配置命名空间来声明连接工厂(适用于 ActiveMQ 4.1 之后的所有版本)。首先,我们必须确保在 Spring 的配置文件中声明了 amq 命名空间:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:jms="http://www.springframework.org/schema/jms"
  xmlns:amq="http://activemq.apache.org/schema/core"
  xsi:schemaLocation="
    http://activemq.apache.org/schema/core
    http://activemq.apache.org/schema/core/activemq-core.xsd
    http://www.springframework.org/schema/jms
    http://www.springframework.org/schema/jms/spring-jms.xsd
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd" >
  
  ...
</beans>

现在我们就可以使用 <amq:connectionFactory> 元素声明连接工厂:

<amq:connectionFatory id="connectionFactory"
                      brokerURL="tcp://localhost:61616" />

注意,<amq:connectionFactory> 元素很明显是为 ActiveMQ 所准备的。如果我们使用不同的消息代理实现,它们不一定会提供 Spring 配置命名空间。如果没有提供的话,那我们就需要使用来装配连接工厂。

在本章的后续内容中,我们会多次使用 connectionFactory bean,但是现在,我们只需要通过配置 brokerURL 属性来告知连接工厂消息代理的位置就足够了。在本例中,brokerURL 属性中的 URL 指定连接工厂要连接到本地机器的 61616 端口(这个端口是 ActiveMQ 监听的默认端口)上的 ActiveMQ。

声明 ActiveMQ 消息目的地

除了连接工厂外,我们还需要消息传递的目的地。目的地可以是一个队列,也可以是一个主题,这取决于应用的需求。

不论使用的是队列还是主题,我们都必须使用特定的消息代理实现类在 Spring 中配置目的地 bean。例如,下面的声明定义了一个 ActiveMQ 队列:

<bean id="queue"
      class="org.apache.activemq.command.ActiveMQQueue"
      c:_="spitter.queue" />

同样,下面的声明定义了一个 ActiveMQ 主题:

<bean id="queue"
      class="org.apache.activemq.command.ActiveMQTopic"
      c:_="spitter.queue" />

在第一个示例中,构造器指定了队列的名称,这样消息代理就能获知该信息,而在接下来示例中,名称则为 spitter.topic。

与连接工厂相似的是,ActiveMQ 命名空间提供了另一种方式来声明队列和主题。对于队列,我们可以使用 <amq:queue> 元素来声明:

<amq:queue id="spittleQueue" physicalName="spittle.alert.queue" />

如果是 JMS 主题,我们可以使用 <amq:topic> 元素来声明:

<amq:queue id="spittleTopic" physicalName="spittle.alert.topic" />

不管是哪种类型,都是借助 physicalName 属性指定消息通道的名称。

到此为止,我们已经看到了如何声明使用 JMS 所需的组件。现在我们已经准备好发送和接收消息了。为此,我们将使用 Spring 的 JmsTemplate —— Spring 对 JMS 支持的核心部分。但是首先,让我们先看看如果没有 JmsTemplate,JMS 是怎样使用的,以此了解 JmsTemplate 到底提供了些什么。

Last updated