ActiveMQ是一个伟大的开源消息代理产品,也是使用JMS进行异步消息传递的最佳选择,接下来我们就搭建并使用ActiveMQ消息代理。
添加spring支持activemq的maven依赖
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-spring</artifactId>
<version>5.14.5</version>
</dependency>
或
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-all</artifactId>
<version>5.14.5</version>
</dependency>
配置web.xml,初始化加载spring配置文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" >
<!-- 加载spring的配置文件 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
配置JMS连接工厂方式一,让它知道如何连接到ActiveMQ,ActiveMQConnectionFactory是ActiveMQ自带的连接工厂,在Spring中可以采用如下方式进行配置,这个配置会默认代理监听localhost的61616端口,也可以使用brokerURL属性指定代理的URL。
<bean id="connectionFactory" class="org.apache.activemq.spring.ActiveMQConnectionFactory" />
<bean id="connectionFactory" class="org.apache.activemq.spring.ActiveMQConnectionFactory"
p:brokerURL="tcp://localhost:61616"/>
配置JMS连接工厂方式二,使用ActiveMQ自己的Spring配置命名空间来声明连接工厂(ActiveMQ4.1之后的版本),但是必须要在Spring的配置文件中声明amq命名空间。
<amq:connectionFactory id="connectionFactory" brokerURL="tcp://localhost:61616"/>
配置ActiveMQ消息目的地方式一:目的地可以是一个队列,也可以是一个主题,不论是哪个,我们都必须使用特定的消息代理类在Spring中配置目的地bean,例如,下面的<bean>声明定义了一个ActiveMQ队列
<!--目的地是一个队列,构造器指定了队列的名称,这样消息代理就能获知该信息-->
<bean id="queue" class="org.apache.activemq.command.ActiveMQQueue" c:_="queue"/>
<!--目的地是一个主题,构造器指定了主题的名称-->
<bean id="topic" class="org.apache.activemq.command.ActiveMQTopic" c:_="topic"/>
配置ActiveMQ消息目的地方式二:使用ActiveMQ命名空间的方式来声明主题和队列
<!--声明队列,physicalName属性指定消息通道的名称-->
<amq:queue id="AlertQueue" physicalName="AlertQueue" />
<!--声明主题,physicalName属性指定消息通道的名称-->
<amq:topic id="AlertTopic" physicalName="AlertTopic" />
配置JmsTemplate,在Spring的配置文件中将它声明为一个bean,它知道如何连接到消息代理,并给它注入刚才实现了JMS的ConnectionFactory接口的bean的引用。
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate"
c:_-ref="connectionFactory"/>
声明一个接口和实现类
import simple.com.entity.Spittle;
public interface AlertSendService {
void sendSpittleAlert(Spittle spittle);
void sendSpittleAlertByC(Spittle spittle);
}
@Component
public class AlertSendServiceImpl implements AlertSendService{
private JmsOperations jmsOperations;
//注入jms模板
@Autowired
public AlertSendServiceImpl(JmsOperations jmsOperations) {
this.jmsOperations = jmsOperations;
}
@Override
public void sendSpittleAlert(Spittle spittle) {
//send()方法第一个参数是指定的目的地名称,即标识消息发送给谁,
通过session创建了一个对象消息:传入一个Spittle对象,返回一个对象消息
jmsOperations.send("spittle.alert.queue",new MessageCreator() {
public Message createMessage(Session session) throws JMSException{
return session.createObjectMessage(spittle);
}
});
}
//使用convertAndSend方法,使用内置的消息转换器(message converter)为我们创建消息
public void sendSpittleAlertByC(Spittle spittle) {
jmsOperations.convertAndSend(spittle);
}
}
与其每次发送消息都指定一个目的地,不如在JmsTemplate装配一个默认的目的地,如下所示:将目的地的名称设置为AlertQueue,但它只是一个名称,它并没有说明你所处理的目的地是什么类型。如果已经存在该名称的队列或主题的话,就会用已有的。如果尚未存在的话,将会创建一个新的目的地(通常是队列)。但是,如果你想指定要创建的目的地的类型的话,那么你可以将之前创建的队列或主题的目的地bean装配起来。
bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate"
c:_-ref="connectionFactory" p:defaultDestinationName="AlertQueue"/>
现在,调用JmsTemplate的send()方法时,我们可以去除第一个参数了:
jmsOperations.send(new MessageCreator() {
public Message createMessage(Session session) throws JMSException{
return session.createObjectMessage(spittle);
}
});