1. ActiveMQ安装

1.1 下载(版本5.14.5)

点我官网下载

1.2 安装

解压下载的压缩文件到任意目录中(eg. C:\Program Files (x86)\apache-activemq-5.14.5),进入%ACTIVEMQ_HOME%/bin目录,根据自己的系统位数,进入32/64目录,点击activemq.bat启动ActiveMQ;

2. ActiveMQ与Spring整合使用

2.1 在Maven中添加ActiveMQ和JMS相关的pom,如下:
  1. <dependency>
  2. <groupId>org.springframework</groupId>
  3. <artifactId>spring-jms</artifactId>
  4. <version>4.2.5.RELEASE</version>
  5. <!--<version>{spring.version}</version>-->
  6. </dependency>
  7. <!-- xbean 如<amq:connectionFactory /> -->
  8. <dependency>
  9. <groupId>org.apache.xbean</groupId>
  10. <artifactId>xbean-spring</artifactId>
  11. <version>3.16</version>
  12. </dependency>
  13. <dependency>
  14. <groupId>org.apache.activemq</groupId>
  15. <artifactId>activemq-core</artifactId>
  16. <version>5.7.0</version>
  17. </dependency>
  18. <dependency>
  19. <groupId>org.apache.activemq</groupId>
  20. <artifactId>activemq-pool</artifactId>
  21. <version>5.12.1</version>
  22. </dependency>复制代码
2.2 添加配置文件spring-activemq.xml

在配置文件中加入以下配置信息,每个配置信息都有具体的解释:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:amq="http://activemq.apache.org/schema/core" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans
  5. http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
  6. http://activemq.apache.org/schema/core
  7. http://activemq.apache.org/schema/core/activemq-core.xsd">
  8. <!--配置连接ActiveMQ的连接基本信息 -->
  9. <amq:connectionFactory id="amqConnectionFactory"
  10. brokerURL="tcp://localhost:61616" userName="admin" password="admin" />
  11. <!-- 配置JMS连接工厂 -->
  12. <bean id="connectionFactory"
  13. class="org.springframework.jms.connection.CachingConnectionFactory">
  14. <constructor-arg ref="amqConnectionFactory" />
  15. <property name="sessionCacheSize" value="100" />
  16. </bean>
  17. <!-- 定义消息队列(Queue) -->
  18. <bean id="demoQueueDestination" class="org.apache.activemq.command.ActiveMQQueue">
  19. <!-- 设置消息队列的名字 -->
  20. <constructor-arg>
  21. <value>testQueue</value>
  22. </constructor-arg>
  23. </bean>
  24. <!-- 配置JMS模板(Queue),Spring提供的JMS工具类,它发送、接收消息。 -->
  25. <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
  26. <property name="connectionFactory" ref="connectionFactory" />
  27. <property name="defaultDestination" ref="demoQueueDestination" />
  28. <property name="receiveTimeout" value="10000" />
  29. <!-- true是topic,false是queue,默认是false -->
  30. <property name="pubSubDomain" value="false" />
  31. </bean>
  32. <!-- 配置消息队列监听者(Queue) -->
  33. <!-- 打开监听器,会立即去消费消息(即,起到实时消费通信的作用) -->
  34. <!-- <bean id="queueMessageListener" class="com.hp.common.listener.QueueMessageListener"></bean> -->
  35. <!-- 显示注入消息监听容器(Queue),配置连接工厂,监听的目标是demoQueueDestination,监听器是上面定义的监听器 -->
  36. <!-- <bean id="queueListenerContainer"
  37. class="org.springframework.jms.listener.DefaultMessageListenerContainer">
  38. <property name="connectionFactory" ref="connectionFactory" />
  39. <property name="destination" ref="demoQueueDestination" />
  40. <property name="messageListener" ref="queueMessageListener" />
  41. </bean>
  42. -->
  43. </beans>复制代码

注:在配置文件中,一定不要忘记加入ActiveMQ和JMS相关的schema

2.3 创建Producer和Consumer相关的Service

创建ProducerService,用于发送信息到消息中心

  1. @Service
  2. public class ProducerService {
  3. @Resource(name = "jmsTemplate")
  4. private JmsTemplate jmsTemplate;
  5. private Queue queue;
  6. /**
  7. * 根据目的地发送消息
  8. */
  9. public void sendMessage(Destination destination, final String msg) {
  10. System.out.println(Thread.currentThread().getName() + " 向队列" + destination.toString()
  11. + "发送消息------->" + msg);
  12. jmsTemplate.send(destination, new MessageCreator() {
  13. public Message createMessage(Session session) throws JMSException {
  14. return session.createTextMessage(msg);
  15. }
  16. });
  17. }
  18. public String send(String userId, String msg) {
  19. System.out.println(
  20. Thread.currentThread().getName() + " 向 " + userId + " 的队列" + userId.toString() + "发送消息------>" + msg);
  21. queue = new ActiveMQQueue(userId);
  22. jmsTemplate.send(queue, new MessageCreator() {
  23. @Override
  24. public Message createMessage(Session session) throws JMSException {
  25. TextMessage message=session.createTextMessage(msg);
  26. message.setStringProperty(userId, msg);
  27. return message;
  28. }
  29. });
  30. return "发送成功";
  31. }
  32. /**
  33. * 向默认目的地发送消息
  34. */
  35. public String sendMessage(final String msg) {
  36. String destination = jmsTemplate.getDefaultDestinationName();
  37. System.out
  38. .println(Thread.currentThread().getName() + " 向队列" + destination + "发送消息---------------------->" + msg);
  39. jmsTemplate.send(new MessageCreator() {
  40. public Message createMessage(Session session) throws JMSException {
  41. return session.createTextMessage(msg);
  42. }
  43. });
  44. return "发送成功";
  45. }
  46. }复制代码

创建ConsumerService,用于接受消息


  1. @Service
  2. public class ConsumerService{
  3. @Resource(name = "jmsTemplate")
  4. private JmsTemplate jmsTemplate;
  5. public String receive(Destination destination) {
  6. TextMessage textMessage = (TextMessage) jmsTemplate.receive(destination);
  7. try {
  8. System.out.println("从队列" + destination.toString() + "收到了消息:\t" + textMessage.getText());
  9. } catch (JMSException e) {
  10. e.printStackTrace();
  11. }
  12. return textMessage.toString();
  13. }
  14. public String receive(String userId) {
  15. Queue queue=new ActiveMQQueue(userId+"?consumer.prefetchSize=4");
  16. Message message = null;
  17. String property=null;
  18. try {
  19. message=jmsTemplate.receive(queue);
  20. property=message.getStringProperty(userId);
  21. System.out.println("从队列" + queue.toString() + "收到了消息:\t" + property);
  22. } catch (JMSException e1) {
  23. // TODO Auto-generated catch block
  24. e1.printStackTrace();
  25. }
  26. return property;
  27. }
  28. }复制代码
2.4 添加Controller,用于曝露接口
  1. @Controller
  2. @RequestMapping(value="/mq")
  3. public class MessageController {
  4. private Logger logger = Logger.getLogger(MessageController.class);
  5. @Resource(name = "demoQueueDestination")
  6. private Destination destination;
  7. @Autowired
  8. private ProducerService producer;
  9. @Autowired
  10. private ConsumerService consumer;
  11. @RequestMapping(value = "/SendMessage", method = RequestMethod.POST,produces="application/json")
  12. @ResponseBody
  13. public void send(@RequestParam(value = "userId",required=false)String userId,@RequestParam(value = "msg")String msg) {
  14. logger.info(Thread.currentThread().getName() + "------------send to jms Start");
  15. if (userId==null||"".equals(userId)) {
  16. producer.sendMessage(destination, msg);
  17. }else {
  18. producer.send(userId, msg);
  19. }
  20. logger.info(Thread.currentThread().getName() + "------------send to jms End");
  21. }
  22. @RequestMapping(value = "/ReceiveMessage", method = RequestMethod.GET)
  23. @ResponseBody
  24. public Object receive(@RequestParam(value = "userId",required=false)String userId) {
  25. logger.info(Thread.currentThread().getName() + "------------receive from jms Start");
  26. String tm=null;
  27. if (userId==null||"".equals(userId)) {
  28. tm = consumer.receive(destination);
  29. } else {
  30. tm = consumer.receive(userId);
  31. }
  32. logger.info(Thread.currentThread().getName() + "------------receive from jms End");
  33. return tm.toString();
  34. }
  35. }复制代码
2.5 配置监听器(ek)

如果在配置文件中打开了监听器的注释,即打开监听器,消费者会立即去消费消息,则还需要添加如下代码:

  1. public class QueueMessageListener implements MessageListener{
  2. @Override
  3. public void onMessage(Message message) {
  4. TextMessage tm=(TextMessage) message;
  5. try {
  6. System.out.println("QueueMessageListener监听到了文本消息:\t"
  7. + tm.getText());
  8. //do other work
  9. } catch (JMSException e) {
  10. // TODO Auto-generated catch block
  11. e.printStackTrace();
  12. }
  13. }
  14. }复制代码

3. 测试

启动tomcat,将Javaweb项目运行在tomcat中,通过postman测试接口和方法
接受消息接口:http://localhost:8080/`{project_neme}`/mq/ReceiveMessage?userId={消息队列名称}
发送消息接口:http://localhost:8080/`{project_neme}`/mq/SendMessage?userId={消息队列名称}&msg={参数}

4. 其他场景及技术应用

场景1: 对于mq队列中的消息,系统需要做一些监控或者问题的跟踪,则需要去查看MQ中的数据,但是有需要保证在查看之后不会被删除,因为在P2P模式中,consumer.receive()后消息之后,消息就被消费,MQ不会发送其他consumer,对于这种场景该如何考虑采用ActiveMQ的何种技术去做?
场景2:将使用JDBC持久化的ActiveMQ转换为其他存储方式(文件存储、Kaha、memory),需要做数据迁移,那如何实现?
解决:对于这两种场景,都可以用消息队列中消息查看的方式去实现;
第一个场景,使用ActiveMQ的Browser可以查看未被消费的信息,这样既保证数据不会被消费,也可以实现自己的其他业务;
第二个场景,可以使用Browser将未被消费的信息拿出来,然后再通过produce.send()的方式,将消息发送到其他存储方式的ActiveMQ上;

以下代码实现了使用Browser读出某个队列中未消费的所有消息,并将它们放到list中

  1. public class BrowersService {
  2. private static final Logger logger=LogManager.getLogger(BrowersService.class);
  3. //配置文件配置的jmsTemplate
  4. @Resource(name = "jmsTemplate")
  5. private JmsTemplate jmsTemplate;
  6. public void getMessageFromQuese(String queueName){
  7. List<String> message=jmsTemplate.browse(queueName, new BrowserCallback<List<String>>() {
  8. @Override
  9. public List<String> doInJms(Session session, QueueBrowser browser) throws JMSException {
  10. Enumeration<TextMessage> enumeration=browser.getEnumeration();
  11. List<String> messages=new ArrayList<>();
  12. while (enumeration.hasMoreElements()) {
  13. TextMessage textMessage = (TextMessage) enumeration.nextElement();
  14. logger.info("Message text: "+ textMessage.getText()
  15. +" ID: "+textMessage.getJMSMessageID());
  16. messages.add(textMessage.getText());
  17. }
  18. return messages;
  19. }
  20. });
  21. logger.info("message from browser "+message);
  22. }
  23. }

ActiveMQ 与 Spring的更多相关文章

  1. ActiveMQ与spring整合

    第一步:引用相关的jar包 <dependency> <groupId>org.springframework</groupId> <artifactId&g ...

  2. activeMQ和spring的整合

    http://www.cnblogs.com/shuai-server/p/8966299.html  这篇博客中介绍了activemq传递消息的两种方式,今天分享的是activemq框架和sprin ...

  3. ActiveMQ集成Spring使用

    现在任何一个框架的使用都会结合spring框架,quartz.cxf与平时常见的Hibernate.mybatis.Struts等都可以与spring集成起来使用,在这里研究了activemq结合sp ...

  4. ActiveMQ整合spring、同步索引库

    1.   Activemq整合spring 1.1. 使用方法 第一步:引用相关的jar包. <dependency> <groupId>org.springframework ...

  5. JAVAEE——宜立方商城09:Activemq整合spring的应用场景、添加商品同步索引库、商品详情页面动态展示与使用缓存

    1. 学习计划 1.Activemq整合spring的应用场景 2.添加商品同步索引库 3.商品详情页面动态展示 4.展示详情页面使用缓存 2. Activemq整合spring 2.1. 使用方法 ...

  6. activeMQ的spring、springboot的DEMO

    一.activeMQ实现spring的demo 1:pom.xml文件 <dependencies> <dependency> <groupId>junit< ...

  7. 淘淘商城项目_同步索引库问题分析 + ActiveMQ介绍/安装/使用 + ActiveMQ整合spring + 使用ActiveMQ实现添加商品后同步索引库_匠心笔记

    文章目录 1.同步索引库问题分析 2.ActiveM的介绍 2.1.什么是ActiveMQ 2.2.ActiveMQ的消息形式 3.ActiveMQ的安装 3.1.安装环境 3.2.安装步骤 4.Ac ...

  8. ActiveMQ学习笔记(6)----ActiveMQ整合Spring开发

    1. 添加依赖 spring 提供了对JMS的支持,需要添加Spring支持jms的包和Spring的核心包,如下: <dependency> <groupId>org.apa ...

  9. 分布式-信息方式-ActiveMQ结合Spring

    ActiveMQ结合 Spring开发■ Spring提供了对JMS的支持,需要添加 Spring支持jms的包,如下: <dependency> <groupId>org.a ...

随机推荐

  1. 3dContactPointAnnotationTool开发日志(三一)

      在玩的时候遇到了一个python的问题: Traceback (most recent call last): File ".\convert.py", line 13, in ...

  2. PAT 甲级 1019 General Palindromic Number

    https://pintia.cn/problem-sets/994805342720868352/problems/994805487143337984 A number that will be ...

  3. 解决pciss_spc导入提示表空间不存在以及扩展失败的问题

    select NAME FROM USER$ ORDER BY NAME ; CREATE USER pciss IDENTIFIED BY pciss ; GRANT DBA TO pciss ; ...

  4. c语言----程序记录

    1.结构体写入文件,读取 #include <stdio.h> #include <string.h> #include <stdlib.h> #define ma ...

  5. Java List部分截取,获得指定长度子集合

    subList方法用于获取列表中指定范围的子列表,该列表支持原列表所支持的所有可选操作.返回列表中指定范围的子列表. 语法 subList(int fromIndex, int toIndex) fr ...

  6. BZOJ 1835 基站选址(DP+线段树)

    # include <cstdio> # include <cstring> # include <cstdlib> # include <iostream& ...

  7. 【bzoj3560】DZY Loves Math V 欧拉函数

    题目描述 给定n个正整数a1,a2,…,an,求 的值(答案模10^9+7). 输入 第一行一个正整数n. 接下来n行,每行一个正整数,分别为a1,a2,…,an. 输出 仅一行答案. 样例输入 3 ...

  8. 【bzoj1495】[NOI2006]网络收费 暴力+树形背包dp

    题目描述 给出一个有 $2^n$ 个叶子节点的完全二叉树.每个叶子节点可以选择黑白两种颜色. 对于每个非叶子节点左子树中的叶子节点 $i$ 和右子树中的叶子节点 $j$ :如果 $i$ 和 $j$ 的 ...

  9. Android四大组件之Intent(续2)

    1.你如何通过一个intent来唤醒activity? this.startActivity(intent,request);      2.什么是显式.隐式的intents? 显式:指定组件名,通常 ...

  10. CF605E Intergalaxy Trips 贪心 概率期望

    (当时写这篇题解的时候,,,不知道为什么,,,写的非常冗杂,,,不想改了...) 题意:一张有n个点的图,其中每天第i个点到第j个点的边都有$P_{i, j}$的概率开放,每天可以选择走一步或者留在原 ...