activeMQ消息中间件的与spring的整合

activemq是基于jetty服务容器的,可在源码中发现。

1.maven依赖jar

<!-- ActiveMQ -->
<dependency>
    <groupId>org.apache.activemq</groupId>
    <artifactId>activemq-core</artifactId>
    <version>5.7.0</version>
</dependency>
<dependency>
    <groupId>org.apache.activemq</groupId>
    <artifactId>activemq-pool</artifactId>
    <version>5.8.0</version>
</dependency>

  注意:这里依赖没有直接引入activemq-all 的依赖,因为activemq-all 会依赖slf4j 日志jar容易和 单独引进的slf4的日志jar冲突,如下(我是单独引进slf4j日志的)

<!-- 日志 -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.12</version>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.7.12</version>
</dependency>

2.生产者 (这里指定的是订阅与发布模式)

<!-- 配置JMS服务提供商  ActiveMQ -->
<bean id="activeMQConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
   <!-- 连接ActiveMQ服务地址 -->
   <property name="brokerURL" value="tcp://mqserver:61616"/>
   <property name="userName" value="admin"/>
   <property name="password" value="admin"/>
</bean>

<!-- 配置ActiveMQ的连接池工厂 -->

<bean id="connectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
   <property name="targetConnectionFactory" ref="activeMQConnectionFactory"/>
   <property name="sessionCacheSize" value="100"/>
</bean>

<!-- 点对点队列 -->
<bean id="defaultQueueDestination" class="org.apache.activemq.command.ActiveMQQueue">
   <constructor-arg index="0" value="cn.zyy.tender.admin.queue.default"/>
</bean>
<!-- 一对多队列 -->
<bean id="defaultTopicDestination" class="org.apache.activemq.command.ActiveMQTopic">
   <constructor-arg index="0" value="cn.zyy.tender.admin.topic.default"/>
</bean>

<!-- spring管理JMS(ActiveMQ) -->
<bean id="singleConnectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">
   <property name="targetConnectionFactory" ref="connectionFactory"/>
</bean>

<!-- spring管理jsmTemplate用于发送消息值ActiveMQ服务 -->
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
   <!-- 指定ActiveMQ连接工厂 -->
   <property name="connectionFactory" ref="singleConnectionFactory"/>
   <!-- 指定消息队列名称 -->
   <property name="defaultDestinationName" value="cn.zyy.tender.admin.topic.default"/>
   <!--<property name="defaultDestination" ref="defaultTopicDestination"/>-->
   <!-- 指定为消息的订阅与发布模式 -->
   <property name="pubSubDomain" value="false"/>
</bean>
这里配置消息队列名称有两种方式,1:直接在jsmTemplate中指点默认目标名称(即:设置defaultDestionationName属性)

2通过defaultDestionation属性引进(就是上面的一对多队列)·


3.消费者配置

订阅模式配置:

<!-- 连接工厂 -->
 <bean id="activeMqConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
     <property name="brokerURL" value="${AvtiveMQ.brokerURL}"/>
     <property name="useAsyncSend" value="true"/>
 </bean>
 <bean id="connectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
     <property name="targetConnectionFactory" ref="activeMqConnectionFactory"/>
     <property name="sessionCacheSize" value="100"/>
 </bean>

 <!-- 点对点队列 -->
<!-- <bean id="defaultQueueDestination" class="org.apache.activemq.command.ActiveMQQueue">
     <constructor-arg index="0" value="cn.zyy.tender.admin.queue.default"/>
 </bean>-->
 <!-- 一对多队列 -->
 <bean id="defaultTopicDestination" class="org.apache.activemq.command.ActiveMQTopic">
     <constructor-arg index="0" value="cn.zyy.tender.admin.topic.default"/>
 </bean>

 <!-- 生产者 -->
 <bean id="jmsQueueTemplate" class="org.springframework.jms.core.JmsTemplate">
     <property name="connectionFactory" ref="connectionFactory"/>
     <property name="pubSubDomain" value="false"/>
 </bean>
 <bean id="jmsTopicTemplate" class="org.springframework.jms.core.JmsTemplate">
     <property name="connectionFactory" ref="connectionFactory"/>
     <!-- 指定为消息的订阅与发布模式 -->
     <property name="pubSubDomain" value="true"/>
 </bean>

 <!-- 消费者 -->
 <bean id="defaultMessageQueueListener" class="com.zyy.tender.admin.jms.DefaultMessageQueueListener"/>
 <bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
     <property name="connectionFactory" ref="connectionFactory"/>
     <!-- 指定队列名称 -->
     <property name="destination" ref="defaultTopicDestination"/>
     <!-- 注入自定监听器,处理队列中消息 -->
     <property name="messageListener" ref="defaultMessageQueueListener"/>
     <property name="sessionTransacted" value="true"/>
     <!--<property name="concurrency" value="4-10"/>-->
     <!-- 指定为消息的订阅与发布模式 -->
     <property name="pubSubDomain" value="true"/>
 </bean>



点对点配置:

<!-- 连接工厂 -->
<bean id="activeMqConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
    <property name="brokerURL" value="${AvtiveMQ.brokerURL}"/>
    <property name="useAsyncSend" value="true"/>
</bean>
<bean id="connectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
    <property name="targetConnectionFactory" ref="activeMqConnectionFactory"/>
    <property name="sessionCacheSize" value="100"/>
</bean>

<!-- 点对点队列 -->
<bean id="defaultQueueDestination" class="org.apache.activemq.command.ActiveMQQueue">
    <constructor-arg index="0" value="cn.zyy.tender.admin.queue.default"/>
</bean>
<!-- 一对多队列 -->
<!--<bean id="defaultTopicDestination" class="org.apache.activemq.command.ActiveMQTopic">
    <constructor-arg index="0" value="cn.zyy.tender.admin.topic.default"/>
</bean>-->

<!-- 生产者 -->
<bean id="jmsQueueTemplate" class="org.springframework.jms.core.JmsTemplate">
    <property name="connectionFactory" ref="connectionFactory"/>
    <property name="pubSubDomain" value="false"/>
</bean>
<bean id="jmsTopicTemplate" class="org.springframework.jms.core.JmsTemplate">
    <property name="connectionFactory" ref="connectionFactory"/>
    <!-- 指定为消息的订阅与发布模式 -->
    <property name="pubSubDomain" value="true"/>
</bean>

<!-- 消费者 -->
<bean id="defaultMessageQueueListener" class="com.zyy.tender.admin.jms.DefaultMessageQueueListener"/>
<bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
    <property name="connectionFactory" ref="connectionFactory"/>
    <!-- 指定队列名称 -->
    <property name="destination" ref="defaultQueueDestination"/>
    <!-- 注入自定监听器,处理队列中消息 -->
    <property name="messageListener" ref="defaultMessageQueueListener"/>
    <property name="sessionTransacted" value="true"/>
    <!--<property name="concurrency" value="4-10"/>-->
    <!-- 指定为消息的订阅与发布模式  这里的订阅模式可由生产者(优先级高)指定-->
    <property name="pubSubDomain" value="false"/>
</bean>

4. 生产者发送消息 

jmsTemplate是交给spring容器,然后注入到spring的bean中,这里是注入到了serviceImpl中

@Resource
private JmsTemplate jmsTemplate;

@Override
public int isShowByPrimaryKeys(String ids) {
    Integer count=0;
    String[] split = ids.split("-");
    for (final String idStr: split) {
        if (StringUtils.isBlank(idStr)) {
            continue;
        }
        jmsTemplate.send(new MessageCreator() {

            @Override
            public Message createMessage(Session session) throws JMSException {
                TextMessage textMessage = session.createTextMessage(idStr);
                return textMessage;
            }
        });
        zyyTenderNewsMapper.isShowByPrimaryKey(Integer.parseInt(idStr));
        count++;
    }
    return count;

}

5.消费者的消息监听器

将这个消息监听器交个spring来管理,然后注入到activeMQ的  jmsContainer中(见上面消费者的配置),可以消息监听器中注入service接口来处理相应的业务需求。

/**
 * MQ消费者
 */
public class DefaultMessageQueueListener implements MessageListener {

   private static Logger _log = LoggerFactory.getLogger(DefaultMessageQueueListener.class);

   @Autowired
   ThreadPoolTaskExecutor threadPoolTaskExecutor;

   public void onMessage(final Message message) {
      // 使用线程池多线程处理
      threadPoolTaskExecutor.execute(new Runnable() {
         public void run() {
            if (message instanceof TextMessage) {
               TextMessage textMessage = (TextMessage) message;
               try {
                  _log.info("消费消息:{}", textMessage.getText());
                  System.out.println("消费消息:"+textMessage.getText());
               } catch (Exception e){
                  e.printStackTrace();
               }
            }
         }
      });
   }

}

6.消息模式

点对点:一个消息只能被一个消费者消费一次。

订阅模式:一个消息可以被多个消费者消费一次。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值