activeMQ的原理及使用

activeMQ底层实现原理:
在讨论具体方式的时候,我们先看看使用activemq需要启动服务的主要过程。
按照JMS的规范,我们首先需要获得一个JMS connection factory.,通过这个connection factory来创建connection.在这个基础之上我们再创建session, destination, producer和consumer。因此主要的几个步骤如下:
1. 获得JMS connection factory. 通过我们提供特定环境的连接信息来构造factory。
2. 利用factory构造JMS connection
3. 启动connection
4. 通过connection创建JMS session.
5. 指定JMS destination.
6. 创建JMS producer或者创建JMS message并提供destination.
7. 创建JMS consumer或注册JMS message listener.
8. 发送和接收JMS message.
9. 关闭所有JMS资源,包括connection, session, producer, consumer等。
Java Message Service:是Java平台上有关面向消息中间件的技术规范。

执行流程:
通过生产者配置文件配置Spring Caching连接工厂和JmsTemplate的类型(Queue,Topic),发布消息时通过调用jmsTemplate的send(“bos_sms”, new MessageCreator())方
法(第一个参数与消费者配置文件中的 监听器 一致,new MessageCreator()是一个接口,通过
mapMessage.setString(“randomCode”, randomCode)添加信息),当消息发布成功之后,消费者会通过消费者配置文件中对应的的监听器(Queue,Topic)监听到消息队列中
有新的消息,则对应的()消费者方法(smsConsumer)执行,该方法需要实现MessageListener 接口

配置信息:
生产者配置:ConnectionFactory生产ConnectionFactory—》定义JmsTemplate的Queue类型
生产发布消息:jmsTemplate.send(“bos_sms”, new MessageCreator() {}) bos_sms:消费者(在消费者配置文件中),new MessageCreator() {}:中的Message存储相关消息具体内容
消费配置:ConnectionFactory生产ConnectionFactory—》定义Queue监听器(监听到有mq,则执行消费者代码)
消费者消费消息:消费者实现MessageListener 接口。

具体代码:

配置生产者.xml(生产者配置信息applicationContext-mq.xml)

<!-- ActiveMQ 连接工厂 -->
    <!-- 真正可以产生Connection的ConnectionFactory,由对应的 JMS服务厂商提供-->
    <!-- 如果连接网络:tcp://ip:61616;未连接网络:tcp://localhost:61616 以及用户名,密码-->
    <!-- <amq:connectionFactory id="amqConnectionFactory"
        brokerURL="tcp://localhost:61616" userName="admin" password="admin"  /> -->
    <bean id="amqConnectionFactory" 
        class="org.apache.activemq.ActiveMQConnectionFactory">
        <property name="brokerURL" value="tcp://localhost:61616"></property>
        <property name="userName" value="admin"></property>
        <property name="password" value="admin"></property>
    </bean>

    <!-- Spring Caching连接工厂 -->
    <!-- Spring用于管理真正的ConnectionFactory的ConnectionFactory -->  
    <bean id="mqConnectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
        <!-- 目标ConnectionFactory对应真实的可以产生JMS Connection的ConnectionFactory -->  
        <property name="targetConnectionFactory" ref="amqConnectionFactory"></property>
        <!-- 同上,同理 -->
        <!-- <constructor-arg ref="amqConnectionFactory" /> -->
        <!-- Session缓存数量 -->
        <property name="sessionCacheSize" value="100" />
    </bean>

     <!-- Spring JmsTemplate 的消息生产者 start-->

    <!-- 定义JmsTemplate的Queue类型 -->
    <bean id="jmsQueueTemplate" class="org.springframework.jms.core.JmsTemplate">
        <!-- 这个connectionFactory对应的是我们定义的Spring提供的那个ConnectionFactory对象 -->  
        <constructor-arg ref="mqConnectionFactory" />
        <!-- 非pub/sub模型(发布/订阅),即队列模式 -->
        <property name="pubSubDomain" value="false" />
    </bean>

    <!-- 定义JmsTemplate的Topic类型 -->
    <bean id="jmsTopicTemplate" class="org.springframework.jms.core.JmsTemplate">
         <!-- 这个connectionFactory对应的是我们定义的Spring提供的那个ConnectionFactory对象 -->  
        <constructor-arg ref="mqConnectionFactory" />
        <!-- pub/sub模型(发布/订阅) -->
        <property name="pubSubDomain" value="true" />
    </bean>

发布消息

 @Autowired
    @Qualifier("jmsQueueTemplate")
    private JmsTemplate jmsTemplate;

    // 发送验证码
    @Action(value = "customer_sendSms")
    public String sendSms() {
        // 生成验证码,存入session
        final String randomCode = RandomStringUtils.randomNumeric(4);
        ServletActionContext.getRequest().getSession().setAttribute(model.getTelephone(), randomCode);
        System.out.println(model.getTelephone() + "生成的验证码为:" + randomCode);
        // 调用程序发送验证码
        // SmsUtils.sendSmsByHTTP(model.getTelephone(), randomCode);
        // 调用mq服务,发送消息
        jmsTemplate.send("bos_sms", new MessageCreator() {

            @Override
            public Message createMessage(Session session) throws JMSException {
                MapMessage mapMessage = session.createMapMessage();
                mapMessage.setString("randomCode", randomCode);
                mapMessage.setString("telephone", model.getTelephone());
                return mapMessage;
            }
        });
        return NONE;
    }

消费者配置xml(消费者配置信息applicationContext.xml)

<!-- ActiveMQ 连接工厂 -->
    <!-- 真正可以产生Connection的ConnectionFactory,由对应的 JMS服务厂商提供-->
    <!-- 如果连接网络:tcp://ip:61616;未连接网络:tcp://localhost:61616 以及用户名,密码-->
    <!-- <amq:connectionFactory id="amqConnectionFactory"
        brokerURL="tcp://localhost:61616" userName="admin" password="admin"  /> -->
    <bean id="amqConnectionFactory" 
        class="org.apache.activemq.ActiveMQConnectionFactory">
        <property name="brokerURL" value="tcp://localhost:61616"></property>
        <property name="userName" value="admin"></property>
        <property name="password" value="admin"></property>
    </bean>


    <!-- Spring Caching连接工厂 -->
    <!-- Spring用于管理真正的ConnectionFactory的ConnectionFactory -->  
    <bean id="connectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
        <!-- 目标ConnectionFactory对应真实的可以产生JMS Connection的ConnectionFactory -->  
        <property name="targetConnectionFactory" ref="amqConnectionFactory"></property>
        <!-- 同上,同理 -->
        <!-- <constructor-arg ref="amqConnectionFactory" /> -->
        <!-- Session缓存数量 -->
        <property name="sessionCacheSize" value="100" />
    </bean>

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

    <!-- 定义Queue监听器 -->
    <jms:listener-container destination-type="queue" container-type="default" 
        connection-factory="connectionFactory" acknowledge="auto">
        <!-- 默认注册bean名称,应该是类名首字母小写  -->
        <jms:listener destination="bos_sms" ref="smsConsumer"/>
    </jms:listener-container>

    <!-- 定义Topic监听器 -->
<!--     <jms:listener-container destination-type="topic" container-type="default"  -->
<!--        connection-factory="connectionFactory" acknowledge="auto"> -->
<!--         <jms:listener destination="spring_topic" ref="topicConsumer1"/> -->
<!--         <jms:listener destination="spring_topic" ref="topicConsumer2"/> -->
<!--     </jms:listener-container> -->

消费者代码:

@Service("smsConsumer")
public class SmsConsumer implements MessageListener {

    @Override
    public void onMessage(Message message) {
        MapMessage mapMessage = (MapMessage) message;
        try {
            // String code = SmsUtils.sendSmsByHTTP(mapMessage.getString("telephone"),
            // mapMessage.getString("randomCode"));
            String code = "000";
            if (code.endsWith("000")) {
                System.out.println("短信发送成功,手机号码:" + mapMessage.getString("telephone") + ",验证码:"
                        + mapMessage.getString("randomCode"));
            } else {
                throw new RuntimeException("短信发送失败");
            }
        } catch (JMSException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}
  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值