ActiveMQ整合Spring(多消费者)

来源:互联网 发布:linux 安装 svn 编辑:程序博客网 时间:2024/05/16 07:22
完整项目下载:activemq和spring整合
项目目录:
src/test/java目录下有main方法测试发送 接受消息
com.ryx.amp包下有发送和监听的两个类  可以使用main方法测试
配置文件中已配置:多个消费者(多线程消费队列),activemq消息异常重发策略

整合过程

maven依赖

<!--activemq  --><dependency><groupId>org.apache.activemq</groupId><artifactId>activemq-all</artifactId><version>5.11.1</version></dependency><dependency><groupId>org.apache.activemq</groupId><artifactId>activemq-pool</artifactId><version>5.11.1</version></dependency>

applicationContext-amq.xml

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:task="http://www.springframework.org/schema/task"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsdhttp://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsdhttp://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.1.xsd"><!-- 加载配置文件 --><context:property-placeholder location="classpath:properties/*.properties" /><!-- 真正可以产生Connection的ConnectionFactory,由对应的 JMS服务厂商提供 --><bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory"><!-- ActiveMQ服务地址 -->        <property name="brokerURL" value="${mq.brokerURL}" />        <property name="userName" value="${mq.userName}"></property>        <property name="password" value="${mq.password}"></property>         <!-- 这里定义重试策略,注意:只有持久化的才会重试-->          <property name="redeliveryPolicyMap" ref="redeliveryPolicyMap"/></bean><!--这里设置各个消息队列的重发机制-->      <bean id="redeliveryPolicyMap" class="org.apache.activemq.broker.region.policy.RedeliveryPolicyMap">          <property name="redeliveryPolicyEntries">              <list>                  <ref bean="bizRedeliveryPolicy"/>                  <!--这里可以设置多个  -->                <!-- <ref bean="bizRedeliveryPolicy2"/>   -->            </list>          </property>      </bean>        <bean id="bizRedeliveryPolicy" class="org.apache.activemq.RedeliveryPolicy">          <!--重发次数 延时、延时系数、延时指数开关、目标(重发等待时间1s, 2s, 4s, 8s)-->          <property name="maximumRedeliveries" value="3"/>          <property name="redeliveryDelay" value="1000"/>          <property name="backOffMultiplier" value="2"/>          <property name="useExponentialBackOff" value="true"/>          <property name="destination" ref="destination"/>      </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="${mq.pool.maxConnections}" /></bean><!-- Spring用于管理真正的ConnectionFactory的ConnectionFactory --><bean id="connectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory"><!-- 目标ConnectionFactory对应真实的可以产生JMS Connection的ConnectionFactory --><property name="targetConnectionFactory" ref="pooledConnectionFactory" /><property name="reconnectOnException" value="true"/></bean><!-- Spring提供的JMS工具类,它可以进行消息发送、接收等 --><!-- 队列模板 --><bean id="activeMqJmsTemplate" class="org.springframework.jms.core.JmsTemplate">      <!-- 这个connectionFactory对应的是我们定义的Spring提供的那个ConnectionFactory对象 -->      <property name="connectionFactory" ref="connectionFactory"/>      <property name="defaultDestination" ref="destination"/>    <!-- 使 deliveryMode, priority, timeToLive设置生效-->        <property name="explicitQosEnabled" value="true" />        <!-- 持久化 如果设置为非持久化MQ服务器重启后MQ中的数据会丢失-->        <property name="deliveryPersistent" value="true"/>        <!--这里注意:如果不开启事务,消息在异常的情况下是不会重试的-->        <property name="sessionTransacted" value="true"/></bean> <bean id="producerMessageSender" class="com.ryx.amq.ProducerMessageSender"/><!--目的地,就是要监听的队列  --><bean id="destination" class="org.apache.activemq.command.ActiveMQQueue"><constructor-arg index="0" value="${queueName}" /></bean><!--这个是sessionAwareQueue目的地 --><bean id="sessionAwareQueue" class="org.apache.activemq.command.ActiveMQQueue"><constructor-arg><value>${queueName}</value></constructor-arg></bean><!-- 可以获取session的MessageListener --><bean id="consumerSessionAwareMessageListener" class="com.ryx.amq.ConsumerSessionAwareMessageListener"/><bean id="sessionAwareListenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer"><property name="connectionFactory" ref="connectionFactory" /><property name="destination" ref="sessionAwareQueue" /><property name="messageListener" ref="consumerSessionAwareMessageListener" /><!-- 这里注意:如果不开启事务,消息在异常的情况下是不会重试的 --><property name="sessionTransacted" value="true"></property><!-- 设置固定的线程数 --><!-- <property name="concurrentConsumers" value="3"></property> --><!-- 设置动态的线程数 --><property name="concurrency" value="2-3"></property><!-- 设置最大的线程数 --><!-- <property name="maxConcurrentConsumers" value="3"></property> --></bean></beans>

Web.xml

<!-- 加载spring容器 --><context-param><param-name>contextConfigLocation</param-name><param-value>classpath:spring/applicationContext-*.xml</param-value></context-param>

ProducerMessageSender.java

package com.ryx.amq;import javax.jms.JMSException;import javax.jms.Message;import javax.jms.Session;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.jms.core.JmsTemplate;import org.springframework.jms.core.MessageCreator;public class ProducerMessageSender {@Autowiredprivate JmsTemplate jmsTemplate;public void SendMessage(final Integer count){jmsTemplate.send(new MessageCreator() {@Overridepublic Message createMessage(Session session) throws JMSException {return session.createTextMessage("这是一首简单的小情歌"+"---->"+count);}});}}

ConsumerSessionAwareMessageListener.java

package com.ryx.amq;import javax.jms.Destination;import javax.jms.JMSException;import javax.jms.Message;import javax.jms.Session;import org.apache.activemq.command.ActiveMQTextMessage;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.jms.core.JmsTemplate;import org.springframework.jms.listener.SessionAwareMessageListener;/** * 队列监听器 * @author broadthinking * */public class ConsumerSessionAwareMessageListener implements SessionAwareMessageListener<Message> {private static final Log log = LogFactory.getLog(ConsumerSessionAwareMessageListener.class);@Autowiredprivate JmsTemplate activeMqJmsTemplate;@Autowiredprivate Destination sessionAwareQueue;public synchronized void onMessage(Message message, Session session) throws JMSException {ActiveMQTextMessage msg = (ActiveMQTextMessage) message;final String ms = msg.getText();System.out.println(Thread.currentThread().getName()+"------>"+ms);//这里是测试异常重发//throw new RuntimeException();}}