实战一 , 实战二 介绍了ActiveMQ的基本概念和配置方式.

本篇将通过一个实例介绍使用spring发送,消费topic, queue类型消息的方法. 不懂topic和queue的google 之.

如图示, TOPIC和QUEUE分别代表一个topic和一个queue消息通道.

  1. TopicMessageProducer向topic发送消息, TopicConsumerA和TopicConsumerB则从topic消费消息.
  2. QueueMessageProducer向Queue发送消息, QueueConsumer从Queue中消费消息

Spring整合JMS

就像对orm, web的支持一样, spring同样支持jms, 为整合jms到已有的项目提供了很多便利的方法. 本篇主要讲实战, 是所以先从配置开始, spring配置jms基本上需要8个部分.

  1. ConnectionFactory. 和jms服务器的连接, 可以是外部的jms server, 也可以使用embedded ActiveMQ Broker.
  2. Destination. 有topic和queue两种方式.
  3. JmsTemplate. spring提供的jms模板.
  4. MessageConverter. 消息转换器.
  5. MessageProducer. 消息生产者.
  6. MessageConsumer. 消息消费者.
  7. MessageListener. 消息监听器
  8. MessageListenerContainer. 消息监听容器

下面以实例的方式介绍上面8个部分.

1. ConnectionFactory

  1. <amq:connectionFactory id="jmsConnectionFactory" brokerURL="vm://localhost" />

brokerURL是指要连接的activeMQ server的地址, activeMQ提供了多种brokerURL, 集体可参见文档.一般我们使用嵌套的ActiveMQ server. 配置如下, 这个配置使用消息的存储机制, 服务器重启也不会丢失消息.

<!--  embedded ActiveMQ Broker -->
<amq:broker useJmx="false" persistent="true">
<amq:persistenceAdapter>
<amq:amqPersistenceAdapter directory="d:/amq"/>
</amq:persistenceAdapter>
<amq:transportConnectors>
<amq:transportConnector uri="tcp://localhost:61616" />
<amq:transportConnector uri="vm://localhost:0" />
</amq:transportConnectors>
</amq:broker>

2. Destination

在实例中我们使用了两种destination

<!--  ActiveMQ destinations  -->
<!-- 使用topic方式-->
<amq:topic name="TOPIC" physicalName="JMS-TEST-TOPIC" />
<!-- 使用Queue方式-->
<amq:queue name="QUEUE" physicalName="JMS-TEST-QUEUE" />

3. JmsTemplate

<!--  Spring JmsTemplate config -->
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory">
<!-- lets wrap in a pool to avoid creating a connection per send -->
<bean class="org.springframework.jms.connection.SingleConnectionFactory">
<property name="targetConnectionFactory" ref="jmsConnectionFactory" />
</bean>
</property>
<!-- custom MessageConverter -->
<property name="messageConverter" ref="defaultMessageConverter" />
</bean>

4. MessageConverter

MessageConverter实现的是org.springframework.jms.support.converter.MessageConverter接口, 提供消息的转换功能. DefaultMessageConverter的实现见附件.

  1. <bean id="defaultMessageConverter" class="com.andyao.activemq.DefaultMessageConverter" />

5. MessageProducer

实例拥有两个消息生产者, 消息生产者都是POJO, 实现见附件.

<!-- POJO which send Message uses  Spring JmsTemplate -->
<bean id="topicMessageProducer" class="com.andyao.activemq.TopicMessageProducer">
<property name="template" ref="jmsTemplate" />
<property name="destination" ref="TOPIC" />
</bean>
<bean id="queueMessageProducer" class="com.andyao.activemq.QueuMessageProducer">
<property name="template" ref="jmsTemplate" />
<property name="destination" ref="QUEUE" />
</bean>

6. MessageConsumer

TOPIC通道有两个消息消费者, QUEUE有一个消息消费者

<!--  Message Driven POJO (MDP) -->
<!-- consumer1 for topic a -->
<bean id="topicConsumerA" class="com.andyao.activemq.TopicConsumerA" />
<!-- consumer2 for topic a -->
<bean id="topicConsumerB" class="com.andyao.activemq.TopicConsumerB" />
<!-- consumer for queue -->
<bean id="queueConsumer" class="com.andyao.activemq.QueueConsumer" />

7. MessageListener

每一个消息消费者都对应一个MessageListener

<bean id="topicListenerA" class="org.springframework.jms.listener.adapter.MessageListenerAdapter">
<constructor-arg ref="topicConsumerA" />
<!-- may be other method -->
<property name="defaultListenerMethod" value="receive" />
<!-- custom MessageConverter define -->
<property name="messageConverter" ref="defaultMessageConverter" />
</bean> <bean id="topicListenerB" class="org.springframework.jms.listener.adapter.MessageListenerAdapter">
<constructor-arg ref="topicConsumerB" />
<!-- may be other method -->
<property name="defaultListenerMethod" value="receive" />
<!-- custom MessageConverter define -->
<property name="messageConverter" ref="defaultMessageConverter" />
</bean> <bean id="queueListener" class="org.springframework.jms.listener.adapter.MessageListenerAdapter">
<constructor-arg ref="queueConsumer" />
<!-- may be other method -->
<property name="defaultListenerMethod" value="receive" />
<!-- custom MessageConverter define -->
<property name="messageConverter" ref="defaultMessageConverter" />
</bean>

8. MessageListenerContainer

有几个MessageListener既有几个MessageListenerContainer

<bean id="topicListenerContainerA" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="jmsConnectionFactory" />
<property name="destination" ref="TOPIC" />
<property name="messageListener" ref="topicListenerA" />
</bean> <bean id="topicListenerContainerB" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="jmsConnectionFactory" />
<property name="destination" ref="TOPIC" />
<property name="messageListener" ref="topicListenerB" />
</bean> <bean id="queueListenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="jmsConnectionFactory" />
<property name="destination" ref="QUEUE" />
<property name="messageListener" ref="queueListener" />
</bean>

Summary

写spring配置文件的时候, 要把MessageProducer, MessageConsumer,MessageListener,MessageListenerContainer几个地方弄清楚:

  1. 可以有一个或者多个消息生产者向同一个destination发送消息.
  2. queue类型的只能有一个消息消费者.
  3. topic类型的可以有多个消息消费者.
  4. 每个消费者对应一个MessageListener和一个MessageListenerContainer.

ActiveMQ5.0实战三:使用Spring发送,消费topic和queue消息的更多相关文章

  1. HttpClient实战三:Spring整合HttpClient连接池

    简介 在微服务架构或者REST API项目中,使用Spring管理Bean是很常见的,在项目中HttpClient使用的一种最常见方式就是:使用Spring容器XML配置方式代替Java编码方式进行H ...

  2. 译: 5. RabbitMQ Spring AMQP 之 Topic 主题

    在上一个教程中,我们提高了消息传递的灵活 我们使用direct交换而不是使用仅能够进行虚拟广播的fanout交换, 并且获得了基于路由key 有选择地接收消息的可能性. 虽然使用direct 交换改进 ...

  3. 5、RabbitMQ - Exchange之 fanout \ 【direct 关键字发送】 \ topic

    pytho系列之 RabbitMQ - Exchange几种模式 RabbitMQ中,所有生产者提交的消息都由Exchange来接受,然后Exchange按照特定的策略转发到Queue进行存储 Rab ...

  4. SpringCloud实战之初级入门(三)— spring cloud config搭建git配置中心

    目录 1.环境介绍 2.配置中心 2.1 创建工程 2.2 修改配置文件 2.3 在github中加入配置文件 2.3 修改启动文件 3. 访问配置中心 1.环境介绍 上一篇文章中,我们介绍了如何利用 ...

  5. 消息中间件系列三:使用RabbitMq原生Java客户端进行消息通信(消费者(接收方)自动确认模式、消费者(接收方)自行确认模式、生产者(发送方)确认模式)

    准备工作: 1)安装RabbitMQ,参考文章:消息中间件系列二:RabbitMQ入门(基本概念.RabbitMQ的安装和运行) 2.)分别新建名为OriginalRabbitMQProducer和O ...

  6. spring(三、spring中的eheche缓存、redis使用)

    spring(三.spring中的eheche缓存.redis使用) 本文主要介绍为什么要构建ehcache+redis两级缓存?以及在实战中如何实现?思考如何配置缓存策略更合适?这样的方案可能遗留什 ...

  7. Spring Boot 2 (三):Spring Boot 2 相关开源软件

    Spring Boot 2 (三):Spring Boot 2 相关开源软件 一.awesome-spring-boot Spring Boot 中文索引,这是一个专门收集 Spring Boot 相 ...

  8. Java并发编程原理与实战三十六:阻塞队列&消息队列

    一.阻塞队列 1.阻塞队列BlockingQueue ---->可以理解成生产者消费者的模式---->消费者要等待到生产者生产出来产品.---->而非阻塞队列ConcurrentLi ...

  9. RabbitMQ实战(三)-高级特性

    0 相关源码 1 你将学到 如何保证消息百分百投递成功 幂等性 如何避免海量订单生成时消息的重复消费 Confirm确认消息.Return返回消息 自定义消费者 消息的ACK与重回队列 限流 TTL ...

随机推荐

  1. mysql异常

    一.Can't connect to MySQL server on 'localhost' (10061)翻译:不能连接到 localhost 上的mysql分析:这说明“localhost”计算机 ...

  2. VS Access DataSet 插入

    在使用vs2008+access数据库,然后又使用了数据集,这时候插入操作遇到了问题,各种乱七八糟.各种头疼的问题就不说了,现在说找到的解决方法: 在xsd文件中插入TableAdapter后,会自动 ...

  3. [leetcode]239. Sliding Window Maximum滑动窗口最大值

    Given an array nums, there is a sliding window of size k which is moving from the very left of the a ...

  4. linux 下的 rsync 文件同步

    rsync是linux下的一款快速增量备份工具Remote Sync,是一款实现远程同步功能的软件,它在同步文件的同时,可以保持原来文件的权限.时间.软硬链接等附加信息.rsync是用 “rsync ...

  5. tp中引入js、css、img的问题

    方法一: 直接把js.css.img放到网站公共目录/Public/下. 然后直接在模板文件中使用__PUBLIC__进行替换. 方法二: 在模块配置文件config.php中配置指定的路径,如下: ...

  6. UI设计如何做好排版?你可以学习一下格式塔原理

    格式塔是一种视觉感知的理论,是研究人们视觉如何将元素组织成群体或整体,从而视觉上进行分类,在设计中,我们使用格式原理能使得我们设计更科学性,更具吸引力.通过格式塔效应,去处理设计中的点.线.面.颜色. ...

  7. centos 挂载u盘

    1.创建一个目录来挂载U盘 mkdir /mnt/usb #创建usb目录挂载U盘 2.插上U盘,查看移动设备状态 fdisk -l #(注意:参数是小写字母 l 不是数字 1) 会看到类似这一行:/ ...

  8. Mybatis Blob和String互转,实现文件上传等。

    这样的代码网上有很多,但是本人亲测有bug, 下面是我写的代码.望参考 @MappedJdbcTypes(JdbcType.BLOB) public class BlobAndStringTypeHa ...

  9. 乞丐版servlet容器第3篇

    4 EventListener接口 让我们继续看SocketConnector中的acceptConnect方法: @Override protected void acceptConnect() t ...

  10. 流程控制 if while for 已及数字类型 进制转换

    一:if 语句 语法一:ifif 条件: code1 code1 code1 语法二:if ...else ... if 条件: code1 code1 code1else: code1 code1 ...