1. 简单项目demo 

    Com.hoo.mq路径下(除了com.hoo.mq.spring)是普通java中使用activeMQ.

    Com.hoo.mq.spring路径下是非web环境spring集成activeMQ。

     Com.tgb.SpringActivemq路径下是web环境下spring mvc集成activeMQ.

  

    目录结构如下:

    

  

    github下载地址:https://github.com/Monkey-mi/TestActiveMQ.git

2. web项目

  2.1 生产者

    spring-activemq.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:xsi="http://www.w3.org/2001/XMLSchema-instance" 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.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/jms
http://www.springframework.org/schema/jms/spring-jms-4.0.xsd
http://activemq.apache.org/schema/core
http://activemq.apache.org/schema/core/activemq-core-5.8.0.xsd"> <!-- 加载activemq的属性配置文件 -->
<context:property-placeholder location="classpath:config/activemq.properties" /> <!-- ActiveMQ 连接工厂 -->
<!-- 真正可以产生Connection的ConnectionFactory,由对应的 JMS服务厂商提供-->
<!-- 如果连接网络:tcp://ip:61616;未连接网络:tcp://localhost:61616 以及用户名,密码-->
<amq:connectionFactory id="amqConnectionFactory"
brokerURL="tcp://localhost:61618" userName="admin" password="topsun" /> <!-- Spring Caching连接工厂 -->
<!-- Spring用于管理真正的ConnectionFactory的ConnectionFactory
org.springframework.jms.connection.CachingConnectionFactory
org.apache.activemq.pool.PooledConnectionFactory
-->
<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" />
<!-- 接收者ID,用于Topic订阅者的永久订阅 clientId 作为客户端的标识,连接同一服务的客户端不能拥有相同的 -->
<property name="clientId" value="client-B" />
</bean> <!-- Spring JmsTemplate 的消息生产者 start--> <!-- 定义JmsTemplate的Queue类型 -->
<bean id="jmsQueueTemplate" class="org.springframework.jms.core.JmsTemplate">
<!-- 这个connectionFactory对应的是我们定义的Spring提供的那个ConnectionFactory对象 -->
<constructor-arg ref="connectionFactory" />
<!-- 非pub/sub模型(发布/订阅),即队列模式 -->
<property name="pubSubDomain" value="false" />
<!-- 订阅消息持久化 -->
<property name="deliveryPersistent" value="true" />
<!-- 配置持久化,同上 deliveryPersistent
<property name="deliveryMode" value="2" />
-->
</bean> <!-- 定义JmsTemplate的Topic类型 -->
<bean id="jmsTopicTemplate" class="org.springframework.jms.core.JmsTemplate">
<!-- 这个connectionFactory对应的是我们定义的Spring提供的那个ConnectionFactory对象 -->
<constructor-arg ref="connectionFactory" />
<!-- pub/sub模型(发布/订阅) -->
<property name="pubSubDomain" value="true" />
<!-- 订阅消息持久化 -->
<property name="deliveryPersistent" value="true" />
<!-- 配置持久化,同上 deliveryPersistent
<property name="deliveryMode" value="2" />
-->
</bean> <!--Spring JmsTemplate 的消息生产者 end--> </beans>

  QueueSender.java

package com.outsideasy.activemq.service;

import java.io.Serializable;

import javax.jms.JMSException;
import javax.jms.MapMessage;
import javax.jms.Message;
import javax.jms.Session; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service; @Component
public class QSender {
//队列名
private static final String QUEUENAME = "outside.order";
@Autowired
@Qualifier("jmsQueueTemplate")
private JmsTemplate jmsTemplate;//通过@Qualifier修饰符来注入对应的bean /**
* 发送一条消息到指定的队列(目标)
* @params s 序列化对象 和 receiver 中的getObject对应
*/
public void orderSend(final Serializable s){
jmsTemplate.send(QUEUENAME, new MessageCreator() {
@Override
public Message createMessage(Session session) throws JMSException {
return session.createObjectMessage(s);
}
});
}
}

  PurchaseOrderService.java

    public void saveAccpetOrderByID(Map<String,Object> params){
int status = getPurchaseOrderStatus(params);
if(status ==10){
params.put("order_status", 20);
mapper.updateOrderStatus(params);
purchaseOrderOperatingService.addPurchaseOrderOperating(params);
//触发PO确认接单
PurchaseOrderVo purchaseOrderVo = mapper.getOrderDetailsByID(params);
PurchaseOrderSender sender = new PurchaseOrderSender();//构造发送数据 这里的对象和接受者对象在项目中的包路径相同,否则无法反序列化
sender.setPur_order_id(purchaseOrderVo.getPur_order_id());
sender.setOrder_bh(purchaseOrderVo.getOrder_bh());
sender.setOrder_status(purchaseOrderVo.getOrder_status());
sender.setAgreement_bh(purchaseOrderVo.getAgreement_bh());
sender.setR_opreate_dt(purchaseOrderVo.getR_opreate_dt());
sender.setSource_type(purchaseOrderVo.getSource_type());
qSender.orderSend(sender);//调用activemq发送消息对象
}else{ }
}

  2.2 消费者

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/jms
http://www.springframework.org/schema/jms/spring-jms-4.0.xsd
http://activemq.apache.org/schema/core
http://activemq.apache.org/schema/core/activemq-core-5.8.0.xsd"> <context:property-placeholder location="classpath:sysconfig/activemq.properties" />
<bean id="qReceiver" class="com.outsideasy.activemq.service.QReceiver"/> <!-- ActiveMQ 连接工厂 -->
<!-- 真正可以产生Connection的ConnectionFactory,由对应的 JMS服务厂商提供-->
<!-- 如果连接网络:tcp://ip:61616;未连接网络:tcp://localhost:61616 以及用户名,密码-->
<amq:connectionFactory id="amqConnectionFactory"
brokerURL="tcp://localhost:61618" userName="admin" password="topsun" /> <!-- Spring Caching连接工厂 -->
<!-- Spring用于管理真正的ConnectionFactory的ConnectionFactory
org.springframework.jms.connection.CachingConnectionFactory
org.apache.activemq.pool.PooledConnectionFactory
-->
<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" />
<!-- 接收者ID,用于Topic订阅者的永久订阅-->
<property name="clientId" value="client-C" />
</bean> <!-- 消息消费者 start-->
<!-- 定义Queue监听器 -->
<jms:listener-container destination-type="queue" container-type="default" connection-factory="connectionFactory" acknowledge="auto">
<jms:listener destination="outside.order" ref="qReceiver"/>
<!-- <jms:listener destination="test.queue" ref="queueReceiver2"/> -->
</jms:listener-container> <!-- 定义Topic监听器 -->
<jms:listener-container destination-type="durableTopic" container-type="default" connection-factory="connectionFactory" acknowledge="auto" client-id="client-C">
<!-- 注意:定义 subscription(即:durableSubscriptionName)持久化主题名字 -->
<!-- <jms:listener destination="test.topic" subscription="topic_receiver1" ref="topicReceiver1"/>
<jms:listener destination="test.topic" subscription="topic_receiver2" ref="topicReceiver2"/> -->
</jms:listener-container> <!-- 消息消费者 end -->
</beans>

  QReceiver.java

package com.outsideasy.activemq.service;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage; import org.springframework.stereotype.Component; import com.outsideasy.activemq.model.PurchaseOrderSender; @Component
public class QReceiver implements MessageListener{ @Override
public void onMessage(Message message) {
try {
/*System.out.println("QueueReceiver2接收到消息:"+((TextMessage)message).getText());*/
ObjectMessage objmsg=(ObjectMessage) message;
PurchaseOrderSender purchaseOrderSender=(PurchaseOrderSender)objmsg.getObject(); //此消息对象和发送者的对象路径相同
System.out.println("QueueReceiver1接收到消息:"+purchaseOrderVo.getPur_order_id());
System.out.println("****:"+purchaseOrderVo.toString());
} catch (JMSException e) {
e.printStackTrace();
}
} }

3. 注意事项

  3.1. 序列化与反序列化问题;

    传输为对象类型为对象:

      生产者和消费者对象的包路径必须一致,否则无法反序列化。

    传输为Map类型:

      value值必须为Integer 、Double 、String...自定义对象无法作为Value传输。否则提示如下错误:

      Only objectified primitive objects, String, Map and List types are allowed

  3.2.权限配置

    3.2.1 服务访问权限及账号密码设置

    在%ACTIVEMQ_HOME%\conf中activemq.xml中<xml 元素参见:ActiveMQ Xml Reference>

<broker ...>
<plugins>
<simpleAuthenticationPlugin>
<users>
<authenticationUser username="admin" password="topsun"
groups="admins,publishers,consumers"/> <authenticationUser username="publisher" password="topsun"
groups="publishers,consumers"/> <authenticationUser username="consumer" password="topsun"
groups="consumers"/> <authenticationUser username="guest" password="topsun"
groups="guests"/>
</users>
</simpleAuthenticationPlugin> <authorizationPlugin>
<map>
<authorizationMap>
<authorizationEntries>
<authorizationEntry queue=">" read="admins" write="admins" admin="admins" />
<authorizationEntry topic=">" read="admins" write="admins" admin="admins" />
<authorizationEntry queue="publishers.>" read="publishers" write="publishers" admin="admins" />
<authorizationEntry queue="consumers." read="consumers" write="consumers" admin="admins" />
<authorizationEntry queue="test" read="guests" write="guests" />
</authorizationEntries>
</authorizationMap>
</map>
</authorizationPlugin>
</plugins> </broker>

 

    3.2.2 ActiveMQ 服务网页控制台(web console)账号密码设置

      需要在%ACTIVEMQ_HOME%\bin中jetty-realm.properties中配置,如下:  

## ---------------------------------------------------------------------------
## Licensed to the Apache Software Foundation (ASF) under one or more
## contributor license agreements. See the NOTICE file distributed with
## this work for additional information regarding copyright ownership.
## The ASF licenses this file to You under the Apache License, Version 2.0
## (the "License"); you may not use this file except in compliance with
## the License. You may obtain a copy of the License at
##
## http://www.apache.org/licenses/LICENSE-2.0
##
## Unless required by applicable law or agreed to in writing, software
## distributed under the License is distributed on an "AS IS" BASIS,
## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
## See the License for the specific language governing permissions and
## limitations under the License.
## --------------------------------------------------------------------------- # Defines users that can access the web (console, demo, etc.)
# username: password [,rolename ...]
admin: admin, admin
user: user, user

  3.3 clientId 标签值

    每个客户端只能在此服务中,只能使用唯一标识值。重复使用会报错。

  参考资料:

    1. http://www.cnblogs.com/kszit/p/3596366.html

    2. http://shmilyaw-hotmail-com.iteye.com/blog/1897635

    3.http://www.cnblogs.com/hoojo/p/active_mq_jms_apache_activeMQ.html

  

ActiveMQ (三):项目实践的更多相关文章

  1. 【项目实践】SpringBoot三招组合拳,手把手教你打出优雅的后端接口

    以项目驱动学习,以实践检验真知 前言 一个后端接口大致分为四个部分组成:接口地址(url).接口请求方式(get.post等).请求数据(request).响应数据(response).如何构建这几个 ...

  2. Hangfire项目实践分享

    Hangfire项目实践分享 目录 Hangfire项目实践分享 目录 什么是Hangfire Hangfire基础 基于队列的任务处理(Fire-and-forget jobs) 延迟任务执行(De ...

  3. Windows on Device 项目实践 1 - PWM调光灯制作

    在前一篇文章<Wintel物联网平台-Windows IoT新手入门指南>中,我们讲解了Windows on Device硬件准备和软件开发环境的搭建,以及Hello Blinky项目的演 ...

  4. Hangfire项目实践

    Hangfire项目实践分享 Hangfire项目实践分享 目录 Hangfire项目实践分享 目录 什么是Hangfire Hangfire基础 基于队列的任务处理(Fire-and-forget ...

  5. MVC项目实践,在三层架构下实现SportsStore-02,DbSession层、BLL层

    SportsStore是<精通ASP.NET MVC3框架(第三版)>中演示的MVC项目,在该项目中涵盖了MVC的众多方面,包括:使用DI容器.URL优化.导航.分页.购物车.订单.产品管 ...

  6. MVC项目实践,在三层架构下实现SportsStore-01,EF Code First建模、DAL层等

    SportsStore是<精通ASP.NET MVC3框架(第三版)>中演示的MVC项目,在该项目中涵盖了MVC的众多方面,包括:使用DI容器.URL优化.导航.分页.购物车.订单.产品管 ...

  7. MVC项目实践,在三层架构下实现SportsStore-03,Ninject控制器工厂等

    SportsStore是<精通ASP.NET MVC3框架(第三版)>中演示的MVC项目,在该项目中涵盖了MVC的众多方面,包括:使用DI容器.URL优化.导航.分页.购物车.订单.产品管 ...

  8. MVC项目实践,在三层架构下实现SportsStore-04,实现分页

    SportsStore是<精通ASP.NET MVC3框架(第三版)>中演示的MVC项目,在该项目中涵盖了MVC的众多方面,包括:使用DI容器.URL优化.导航.分页.购物车.订单.产品管 ...

  9. MVC项目实践,在三层架构下实现SportsStore-05,实现导航

    SportsStore是<精通ASP.NET MVC3框架(第三版)>中演示的MVC项目,在该项目中涵盖了MVC的众多方面,包括:使用DI容器.URL优化.导航.分页.购物车.订单.产品管 ...

  10. MVC项目实践,在三层架构下实现SportsStore-06,实现购物车

    SportsStore是<精通ASP.NET MVC3框架(第三版)>中演示的MVC项目,在该项目中涵盖了MVC的众多方面,包括:使用DI容器.URL优化.导航.分页.购物车.订单.产品管 ...

随机推荐

  1. bzoj 1564 [NOI2009]二叉查找树(树形DP)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1564 [题意] 给定一个Treap,总代价为深度*距离之和.可以每次以K的代价修改权值 ...

  2. 20155306 2016-2017-2 《Java程序设计》第6周学习总结

    20155306 2016-2017-2 <Java程序设计>第6周学习总结 教材学习内容总结 第十章 输入/输出 10.1 InputStream与OutputStream 如果要将数据 ...

  3. Struts S2-052漏洞利用之Meterpreter(CVE-2017-9805)

    Struts S2-052漏洞爆出来已经快一周了,大家可能更想知道其危害~鸡肋? 这里就直接给出漏洞利用拿Meterpreter的过程,想了解更多的请参考其他文章,下面是实验演示部分.Struts S ...

  4. POJ 3164 Command Network ( 最小树形图 朱刘算法)

    题目链接 Description After a long lasting war on words, a war on arms finally breaks out between littlek ...

  5. E - Sudoku HDU - 5547 (搜索+暴力)

    题目链接:https://cn.vjudge.net/problem/HDU-5547 具体思路:对于每一位上,我们可以从1到4挨着去试, 具体判断这一位可不可以的时候,看当前这一位上的行和列有没有冲 ...

  6. Java并发编程(4)--生产者与消费者模式介绍

    一.前言 这种模式在生活是最常见的,那么它的场景是什么样的呢? 下面是我假象的,假设有一个仓库,仓库有一个生产者和一个消费者,消费者过来消费的时候会检测仓库中是否有库存,如果没有了则等待生产,如果有就 ...

  7. 【2017-10-1】雅礼集训day1

    今天的题是ysy的,ysy好呆萌啊. A: 就是把一个点的两个坐标看成差分一样的东西,以此作为区间端点,然后如果点有边->区间没有交. B: cf原题啊.....均摊分析,简单的那种. 线段树随 ...

  8. EPC摘抄

    S6a MME – HSS 完成用户位置信息的交换和用户签约信息的管理,传送控制面信息 Diameter MME:主要负责信令处理及移动性管理,功能包括:NAS信令及其安全:跟踪区域(Tracking ...

  9. git —— 分支

    git中每一个分支相当于一个时间线 并列且相互平行 控制用指针控制~ 1.第一种创建命令: $ git branch 分支名称 —— 创建分支 $ git checkout 分支名称 —— 切换分支 ...

  10. No.1 selenium学习之路之浏览器操作

    selenium基础,首先就是浏览器的相关操作 下面描述几种浏览器的常用操作 1.打开浏览器 webdriver后面添加想要打开的浏览器 Ie或者Chrome 2.打开指定页面(百度) 3.休眠时间 ...