ActiveMQ执行流程

来源:互联网 发布:windows media center 编辑:程序博客网 时间:2024/06/05 13:27
mq执行需要开启mq服务器
MQ就是我主线程可能要发送一个短信,但是这个短信不是自己的程序,如果放到主程序里面,这个短信发送失败,我整个程序都无法执行下去了.所以我们将发送短信这个功能抽取出来,在主线程中使用mq,一旦我需要发送短信的时候就创建一个生产者,创建完毕主线程就继续执行,抽取出来的功能使用监听,一旦监听到主线程生产了一条信息,就立刻执行消费将短信发送出去
MQ具体操作步骤(Spring整合)
1.导入依赖
Spring开发测试

<dependencies>

    <dependency>

       <groupId>org.springframework</groupId>

       <artifactId>spring-context</artifactId>

       <version>4.1.7.RELEASE</version>

    </dependency>

    <dependency>

       <groupId>org.springframework</groupId>

       <artifactId>spring-test</artifactId>

       <version>4.1.7.RELEASE</version>

    </dependency>

    <dependency>

       <groupId>junit</groupId>

       <artifactId>junit</artifactId>

       <version>4.12</version>

    </dependency>
    ActiveMQ

<dependency>

       <groupId>org.apache.activemq</groupId>

       <artifactId>activemq-all</artifactId>

       <version>5.14.0</version>

    </dependency>
    Spring整合activeMQ

    <dependency>

       <groupId>org.springframework</groupId>

       <artifactId>spring-jms</artifactId>

       <version>4.1.7.RELEASE</version>

    </dependency>

 </dependencies>

2.编写生产者
  2.1配置applicationcontext-mq.xml中的配置
注意!!!!!
我们这里的connectionFactory是bean的名字,但是我们这个applicationContxt-mq.xml是 要引入到applicationContext.xml中的,所以我们要注意名字重复(项目里面就是名字重复了,然后改成的mqconnectionFactory)

<?xmlversion="1.0"encoding="UTF-8"?>

<beansxmlns="http://www.springframework.org/schema/beans"

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:aop="http://www.springframework.org/schema/aop"

    xmlns:context="http://www.springframework.org/schema/context"

    xmlns:jdbc="http://www.springframework.org/schema/jdbc"xmlns:tx="http://www.springframework.org/schema/tx"

    xmlns:jpa="http://www.springframework.org/schema/data/jpa"xmlns:task="http://www.springframework.org/schema/task"

    xmlns:amq="http://activemq.apache.org/schema/core"

    xmlns:jms="http://www.springframework.org/schema/jms"

    xsi:schemaLocation="

       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd

       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd

       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd

       http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.1.xsd

       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd

       http://www.springframework.org/schema/data/jpa

       http://www.springframework.org/schema/data/jpa/spring-jpa.xsd

       http://www.springframework.org/schema/jms

        http://www.springframework.org/schema/jms/spring-jms.xsd

       http://activemq.apache.org/schema/core

        http://activemq.apache.org/schema/core/activemq-core-5.8.0.xsd ">

    

    <!--扫描包 -->

    <context:component-scanbase-package="cn.itcast.activemq"/>

    <!-- ActiveMQ 连接工厂 -->

   <!-- 真正可以产生Connection的ConnectionFactory,由对应的 JMS服务厂商提供-->

   <!-- 如果连接网络:tcp://ip:61616;未连接网络:tcp://localhost:61616 以及用户名,密码-->
     <beanid="amqConnectionFactory"class="org.apache.activemq.ActiveMQConnectionFactory">
        <propertyname="brokerURL"value="tcp://localhost:61616"></property>
        <propertyname="userName"value="admin"></property>
        <propertyname="password"value="admin"></property>
    </bean>

   <!-- Spring Caching连接工厂 -->

   <!-- Spring用于管理真正的ConnectionFactory的ConnectionFactory --> 

   <beanid="connectionFactory"class="org.springframework.jms.connection.CachingConnectionFactory">

       <!-- 目标ConnectionFactory对应真实的可以产生JMS Connection的ConnectionFactory --> 

       <propertyname="targetConnectionFactory"ref="amqConnectionFactory"></property>

       <!--作用同上 -->

       <!-- <constructor-arg ref="amqConnectionFactory" /> -->

       <!-- Session缓存数量 -->

       <propertyname="sessionCacheSize"value="100"/>

   </bean>

 <!-- 定义JmsTemplate的Queue类型 -->

   <beanid="jmsQueueTemplate"class="org.springframework.jms.core.JmsTemplate">

       <!-- 这个connectionFactory对应的是我们定义的Spring提供的那个ConnectionFactory对象 --> 

       <constructor-argref="connectionFactory"/>

       <!-- 非pub/sub模型(发布/订阅),即队列Queue模式 -->

       <propertyname="pubSubDomain"value="false"/>

   </bean>


   <!-- 定义JmsTemplate的Topic类型 -->

   <beanid="jmsTopicTemplate"class="org.springframework.jms.core.JmsTemplate">

        <!-- 这个connectionFactory对应的是我们定义的Spring提供的那个ConnectionFactory对象 --> 

       <constructor-argref="connectionFactory"/>

       <!-- pub/sub模型(发布/订阅),即主题Topic模式 -->

       <propertyname="pubSubDomain"value="true"/>

   </bean>
 </beans>
     2.2完成生产者的代码
这里注入的是jmsQueueTemplate   使用的是queue类型如果用Topic类型的话就将Qualifier内容换成jmsTopicTemplate
(依赖注入,二个都是一种类型,指定名字来使用哪个)
Queue和Topic的区别:1.Queue使用的话生产一个信息  只可以被消费一次  但没有使用时间的限制
                   2.Topic使用的话生产一个信息  可以被消费无数次  但一段时间不用就过期了

@Component

publicclassQueueSender {

    // 注入jmsTemplate

    @Autowired

    @Qualifier("jmsQueueTemplate")

    privateJmsTemplatejmsTemplate;



          
          /这里是截取的mq语句  上面的主线程代码    
    jmsTemplate.send("bos_couriersmse",newMessageCreator() {
            @Override
            publicMessage createMessage(Session session) throws JMSException {
                MapMessagemapMessage= session.createMapMessage();
                mapMessage.setString("telephone","17621777565");// 快递员电话(需发送短信)
                mapMessage.setString("num","1231");// 验证码
                mapMessage.setString("sendAddres","bej");// 寄件地址
                mapMessage.setString("sendName","李四");// 寄件人
                mapMessage.setString("sendMobile","123131");// 寄件人电话
                //mapMessage.setString("sendMobileMsg", order.getSendMobileMsg()); // 快递员稍话
                
                returnmapMessage;
            }
    });
     //下面的主线程代码



3.编写消费者代码
编写消费者的代码,只需要类实现MessageListener接口,用来监听MQ中的内容
@Component(value="queueConsumerContent")
publicclass QueueConsumerContent implementsMessageListener {
    // 如果MQ中有数据,获取数据
    publicvoid onMessage(Message message) {
        MapMessagemapMessage= (MapMessage)message;
        try{
            Stringtelephone = mapMessage.getString("telephone");
            Stringnum = mapMessage.getString("num");
            StringsendAddres = mapMessage.getString("sendAddres");
            StringsendName = mapMessage.getString("sendName");
            StringsendMobile = mapMessage.getString("sendMobile");
            StringsendMobileMsg = mapMessage.getString("sendMobileMsg");
            SendSmsResponsesendSms = SmsDemoUtils2.sendSms(telephone,num,sendAddres,sendName,sendMobile);
            StringsmsCode = sendSms.getCode();
        //  String smsCode = "OK";
            if(smsCode.equals("OK")){
                System.out.println("速运快递 短信序号:"+num+",取件地址:"+sendAddres+",联系人:"+sendName+",手机:"+sendMobile+",快递员捎话:"+sendMobileMsg);
            }
        }catch (Exception e) {
            //TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    
 3.1编写消费的配置文件

 <!-- 消息消费者 start-->

    <!-- 定义Queue监听器,auto表示自动告知已收到-->

   <!-- 定义Queue监听器

       destination-type="queue":表示目标类型,queue表示队列类型

       container-type="default":表示容器类型,采用默认

       acknowledge="auto":表示应答类型,auto表示自动应答,即接收到消息,立即自动消费

     -->

   <jms:listener-containerdestination-type="queue"container-type="default"connection-factory="connectionFactory"acknowledge="auto">

       <!-- test.queue:表示名称; queueConsumer1:表示注入的对象 -->

       <jms:listenerdestination="spring_queue"ref="queueConsumer1"/>

       <jms:listenerdestination="spring_queue"ref="queueConsumer2"/>

   </jms:listener-container>

   


   <!-- 定义Topic监听器,auto表示自动告知已收到-->

   <jms:listener-containerdestination-type="topic"container-type="default"connection-factory="connectionFactory"acknowledge="auto">

       <jms:listenerdestination="spring_topic"ref="topicConsumer1"/>

        <jms:listenerdestination="spring_topic"ref="topicConsumer2"/>

   </jms:listener-container>