4.1 ActiveMQ和Spring集成
由于在项目中一般用的环境都是spring,所以需要知道,spring怎么集成ActiveMQ。
4.1.1 搭建提供者项目
第一步:创建一个 Maven 的项目,名为:spring-activemq-producer,导入 jar
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.bjsxt.activemq</groupId>
<artifactId>spring-activemq-producer</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>war</packaging>
<!-- 设置公共属性,可以被引用 ${attribute} -->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<junit.version>4.12</junit.version>
<spring.version>4.3.19.RELEASE</spring.version>
<activemq.version>5.15.6</activemq.version>
</properties>
<dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.1.26</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.7.1</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-all</artifactId>
<version>${activemq.version}</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-pool</artifactId>
<version>${activemq.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>spring-activemq-producer</finalName>
</build>
</project>
第二步:创建并配置,activemq-config.properties 文件
## ActiveMQ config
activemq.brokerURL=tcp://192.168.2.58:61616
activemq.username=xxx
activemq.password=xxx
activemq.pool.maxConnections=10
## queue name
activemq.mailQueue=mailQueue
第三步:创建并配置 spring-context.xml 文件
该配置文件,用于加载相关 properties 文件,包的扫描,和导入 spring-activemq.xml 文件。
<?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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd"
default-autowire="byName" default-lazy-init="false">
<!-- 读入配置属性文件 -->
<bean id="PropertyPlaceholderConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:activemq-config.properties" />
</bean>
<!-- 注释配置 -->
<context:annotation-config />
<!-- 扫描包起始位置 -->
<context:component-scan base-package="com.bjsxt" />
<!-- proxy-target-class默认"false",更改为"ture"使用CGLib动态代理 -->
<aop:aspectj-autoproxy proxy-target-class="true" />
<import resource="classpath:spring/spring-activemq.xml" />
</beans>
第四步:创建并配置 spring-context.xml 文件
<?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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd"
default-autowire="byName" default-lazy-init="false">
<!-- 第三方MQ工厂: ConnectionFactory -->
<bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<!-- ActiveMQ服务地址 -->
<property name="brokerURL" value="${activemq.brokerURL}" />
<property name="userName" value="${activemq.username}"></property>
<property name="password" value="${activemq.password}"></property>
</bean>
<!--
ActiveMQ为我们提供了一个PooledConnectionFactory,通过往里面注入一个ActiveMQConnectionFactory
可以用来将Connection、Session和MessageProducer池化,这样可以大大的减少我们的资源消耗,要依赖于 activemq-pool包
-->
<bean id="pooledConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory">
<property name="connectionFactory" ref="targetConnectionFactory" />
<property name="maxConnections" value="${activemq.pool.maxConnections}" />
</bean>
<!-- Spring用于管理真正的ConnectionFactory的ConnectionFactory -->
<bean id="connectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">
<!-- 目标ConnectionFactory对应真实的可以产生JMS Connection的ConnectionFactory -->
<property name="targetConnectionFactory" ref="pooledConnectionFactory" />
</bean>
<!-- Spring提供的JMS工具类,它可以进行消息发送、接收等 -->
<!-- 队列模板 -->
<bean id="mailJmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<!-- 这个connectionFactory对应的是我们定义的Spring提供的那个ConnectionFactory对象 -->
<property name="connectionFactory" ref="connectionFactory"/>
<property name="defaultDestinationName" value="${activemq.mailQueue}"></property>
</bean>
</beans>
第五步:创建 MailDomain 实体类
public class MailDomain implements Serializable {
private static final long serialVersionUID = 6294283608053534669L;
/**
* 发件人
*/
private String from;
/**
* 收件人
*/
private String to;
/**
* 主题
*/
private String subject;
/**
* 邮件内容
*/
private String content;
// 省略 setter 和 getter
}
第六步:创建 MailMQProducer 类
此类用于发送数据,所有的Queue都是一样的,如果需要添加其他的queue,只要添加相对应的配置和类即可。
@Service("mailMQProducer")
public class MailMQProducer {
@Autowired
private JmsTemplate mailJmsTemplate;
public void sendMail(final MailDomain mail) {
mailJmsTemplate.send(new MessageCreator() {
public Message createMessage(Session session) throws JMSException {
return session.createTextMessage(JSON.toJSONString(mail));
}
});
}
}
第七步:测试!!
在 test/src/java 创建一个测试类
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:spring/spring-context.xml")
public class MailProducerTest {
@Autowired
private MailMQProducer mailMQProducer;
@Test
public void send() {
MailDomain mail = new MailDomain();
mail.setTo("[email protected]");
mail.setSubject("text activemq !");
mail.setContent("test content");
this.mailMQProducer.sendMail(mail);
}
}
运行后在管理平台可以看到,队列中有数据。
4.1.2 搭建消费者项目
第一步:创建一个 Maven 的项目,名为:spring-activemq-comsumer,导入 jar。
第二步:创建并配置,activemq-config.properties 文件
第三步:创建并配置 spring-context.xml 文件
前三步和提供者的步骤一样,省略。
第四步:创建 MailQueueMessageListener 类 和 MailDomain 实体类。
该类必须实现 MessageListener 接口,用于监听并处理收到的消息。
mailService.sendMail(mail); 此处的代码只打印了接受到的信息,省略。
public class MailQueueMessageListener implements MessageListener {
@Autowired
private MailService mailService;
public void onMessage(Message message) {
try {
TextMessage textMessage = (TextMessage) message;
final String content = textMessage.getText();
MailDomain mail = JSON.parseObject(content, MailDomain.class);
if (mail == null) {
// 打日志
return ;
}
mailService.sendMail(mail);
} catch (Exception e) {
e.printStackTrace();
}
}
}
第五步:创建并配置 spring-activemq.xml 文件
<?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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd"
default-autowire="byName" default-lazy-init="false">
<!-- 第三方MQ工厂: ConnectionFactory -->
<bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<!-- ActiveMQ服务地址 -->
<property name="brokerURL" value="${activemq.brokerURL}" />
<property name="userName" value="${activemq.username}"></property>
<property name="password" value="${activemq.password}"></property>
</bean>
<!--
ActiveMQ为我们提供了一个PooledConnectionFactory,通过往里面注入一个ActiveMQConnectionFactory
可以用来将Connection、Session和MessageProducer池化,这样可以大大的减少我们的资源消耗,要依赖于 activemq-pool包
-->
<bean id="pooledConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory">
<property name="connectionFactory" ref="targetConnectionFactory" />
<property name="maxConnections" value="${activemq.pool.maxConnections}" />
</bean>
<!-- Spring用于管理真正的ConnectionFactory的ConnectionFactory -->
<bean id="connectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">
<!-- 目标ConnectionFactory对应真实的可以产生JMS Connection的ConnectionFactory -->
<property name="targetConnectionFactory" ref="pooledConnectionFactory" />
</bean>
<!-- Spring提供的JMS工具类,它可以进行消息发送、接收等 -->
<!-- 队列模板 -->
<bean id="mailJmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<!-- 这个connectionFactory对应的是我们定义的Spring提供的那个ConnectionFactory对象 -->
<property name="connectionFactory" ref="connectionFactory"/>
<property name="defaultDestinationName" value="${activemq.mailQueue}"></property>
</bean>
<!--这个是目的地:mailQueue -->
<bean id="mailQueue" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg>
<value>${activemq.mailQueue}</value>
</constructor-arg>
</bean>
<!-- 配置自定义监听:MessageListener -->
<bean id="mailQueueMessageListener" class="com.bjsxt.comsumer.listeners.MailQueueMessageListener"></bean>
<!-- 将连接工厂、目标对了、自定义监听注入jms模板 -->
<bean id="sessionAwareListenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory" />
<property name="destination" ref="mailQueue" />
<property name="messageListener" ref="mailQueueMessageListener" />
</bean>
</beans>
与提供者的配置不一样,多了 MailQueueMessageListener 的配置,如下图
第六步,在 test/src/java 里面创建一个测试类
消费者消费在Listener中,所有只需要读取配置,Listener被Spring实例化后,自己会运行。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:spring/spring-context.xml")
public class MailConsumerTest {
@Test
public void mailConsumerTest() throws Exception {
Thread.sleep(Integer.MAX_VALUE);
}
}
在ActiveMQ的管理平台中,看见数据已经被消费
数据也成功打印出来