- 浏览: 7936132 次
- 性别:
- 来自: 广州
文章分类
- 全部博客 (2425)
- 软件工程 (75)
- JAVA相关 (662)
- ajax/web相关 (351)
- 数据库相关/oracle (218)
- PHP (147)
- UNIX/LINUX/FREEBSD/solaris (118)
- 音乐探讨 (1)
- 闲话 (11)
- 网络安全等 (21)
- .NET (153)
- ROR和GOG (10)
- [网站分类]4.其他技术区 (181)
- 算法等 (7)
- [随笔分类]SOA (8)
- 收藏区 (71)
- 金融证券 (4)
- [网站分类]5.企业信息化 (3)
- c&c++学习 (1)
- 读书区 (11)
- 其它 (10)
- 收藏夹 (1)
- 设计模式 (1)
- FLEX (14)
- Android (98)
- 软件工程心理学系列 (4)
- HTML5 (6)
- C/C++ (0)
- 数据结构 (0)
- 书评 (3)
- python (17)
- NOSQL (10)
- MYSQL (85)
- java之各类测试 (18)
- nodejs (1)
- JAVA (1)
- neo4j (3)
- VUE (4)
- docker相关 (1)
最新评论
-
xiaobadi:
jacky~~~~~~~~~
推荐两个不错的mybatis GUI生成工具 -
masuweng:
(转)JAVA获得机器码的实现 -
albert0707:
有些扩展名为null
java 7中可以判断文件的contenttype了 -
albert0707:
非常感谢!!!!!!!!!
java 7中可以判断文件的contenttype了 -
zhangle:
https://zhuban.me竹板共享 - 高效便捷的文档 ...
一个不错的网络白板工具
Spring和ActiveMQ整合需要在项目中包含以下这几个jar包(缺一不可):activeio-core-3.1.4.jar,activemq-all-5.13.2.jar,activemq-pool-5.13.2.jar,commons-pool2-2.4.2.jar,这些jar可以在ActiveMQ的安装包中的/lib/optional/下找到,或者从这里下载。
配置ConnectionFactory
ConnectionFactory是用于产生到JMS服务器的链接的,Spring为我们提供了多个ConnectionFactory,有SingleConnectionFactory和CachingConnectionFactory。SingleConnectionFactory对于建立JMS服务器链接的请求会一直返回同一个链接,并且会忽略Connection的close方法调用。CachingConnectionFactory继承了SingleConnectionFactory,所以它拥有SingleConnectionFactory的所有功能,同时它还新增了缓存功能,可以缓存Session, MessageProducer和MessageConsumer。
Spring提供的ConnectionFactory只是Spring用于管理ConnectionFactory的,真正产生到JMS服务器链接的ConnectionFactory还得是JMS服务厂商提供的,并且需要把它注入到Spring提供的ConnectionFactory中,这里使用ActiveMQ提供的ConnectionFactory,所以定义如下(10.10.195.187是博主的测试ip地址):
<bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://10.10.195.187:61616" />
</bean>
<bean id="connectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">
<property name="targetConnectionFactory" ref="targetConnectionFactory"/>
</bean>
ActiveMQ为我们提供了一个PooledConnectionFactory,通过往里面注入一个ActiveMQConnectionFactory可以用来将Connection, Session和MessageProducer池化,这样可以大大的减少我们的资源消耗。当使用PooledConnectionFactory时,我们在定义一个ConnectionFactory时这样定义:
<bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://10.10.195.187:61616" />
</bean>
<bean id="poolConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory" >
<property name="connectionFactory" ref="targetConnectionFactory" />
<property name="maxConnections" value="10"/>
</bean>
<bean id="connectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">
<property name="targetConnectionFactory" ref="poolConnectionFactory"/>
</bean>
这里也可以去掉spring提供的SingleConnectionFactory,类似这样:
<bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://10.10.195.187:61616" />
</bean>
<bean id="connectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory" >
<property name="connectionFactory" ref="targetConnectionFactory" />
<property name="maxConnections" value="10"/>
</bean>
配置消息发送(生产)者
配置好ConnectionFactory之后我们就需要配置生产者。生产者负责生产消息并发送到JMS服务器,这通常对应的是我们的一个业务逻辑服务实现类。但是我们的服务实现类是怎么进行消息的发送的呢?这通常是利用Spring为我们提供的JmsTemplate类来实现,所以配置生产者其实最核心的就是配置进行消息发送的JmsTemplate。对于消息发送者而言,它在发送消息的时候要知道自己该往哪里发,为此,我们在定义JmsTemplate的时候需要往里面注入一个Spring提供的ConnectionFactory对象。
spring配置文件中添加:
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="poolConnectionFactory"/>
</bean>
在Java相关处理文件中添加(这里用的是@Inject注解,当然也可以用@Autowired):
@Inject
@Named("jmsTemplate")
private JmsTemplate jmsTemplate;
这样就可以通过jmsTemplate对象来处理相关信息,譬如:
jmsTemplate.convertAndSend("sqlQueue",sql);
真正利用JmsTemplate进行消息发送的时候,我们需要知道消息发送的目的地,即Destination。在Jms中有一个用来表示目的地的Destination接口,它里面没有任何方法定义,只是用来做一个标志而已。当我们在使用JmsTemplate进行消息发送时没有指定destination的时候将使用默认的Destination。默认Destination可以通过在定义jmsTemplate bean对象时通过属性defaultDestination或defaultDestinationName来进行诸如,defaultDestinationName对于的就是一个普通字符串。在ActiveMQ中实现了两种类型的Destination,一个是点对点的ActiveMQQueue,另一个就是支持订阅-发布模式的ActiveMQTopic。
<bean id="queueDestination" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg>
<value>sqlQueue</value>
</constructor-arg>
</bean>
<bean id="topicDestination" class="org.apache.activemq.command.ActiveMQTopic">
<constructor-arg>
<value>topic</value>
</constructor-arg>
</bean>
对面上面的那个例子可以在Java程序中添加:
@Inject
@Named("queueDestination")
private Destination queueDestination;
进而【jmsTemplate.convertAndSend(“sqlQueue”,sql);】可以改为【jmsTemplate.convertAndSend(queueDestination,sql);】
也可以这样修改jmsTemplate:
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="connectionFactory"/>
<property name="defaultDestination" ref="queueDestination"/>
</bean>
或者:
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="connectionFactory"/>
<property name="defaultDestinationName" value="sqlQueue"/>
</bean>
进而在java程序中这样调用:jmsTemplate.convertAndSend(sql);
配置消息接收(消费)者
生产者往指定目的地Destination发送消息后,接下来就是消费者对指定目的地的消息进行消费了。那么消费者是如何知道有生产者发送消息到指定目的地Destination了呢?这是通过Spring为我们封装的消息监听容器MessageListenerContainer实现的,它负责接收信息,并把接收到的信息分发给真正的MessageListener进行处理。每个消费者对应每个目的地都需要有对应的MessageListenerContainer。对于消息监听容器而言,除了要知道监听哪个目的地之外,还需要知道到哪里去监听,也就是说它还需要知道去监听那个JMS服务器,这是通过在配置MessageConnectionFactory的时候往里面注入一个ConnectionFactory来实现的。所以我们在配置一个MessageListenerContainer的时候有三个属性必须指定,一个是表示从哪里监听的ConnectionFactory,一个是表示监听什么的Destination,一个是接收到消息以后进行消息处理的MessageListener.
Spring为我们听过了两种类型的MessageListenerContainer:SimpleMessageListenerContainer和DefaultMessageListenerContainer。MessageListenerContainer:SimpleMessageListenerContainer会在一开始的时候就创建一个会话Session和消费者Consumer,并且会适用标准的JMS的MessageConsumer.setMessageListener()方法注册监听器让JMS提供调用监听器的回调函数。它不会动态的适应运行时需要和参与外部的事务管理。兼容性方面,它非常接近于独立的JMS规范,但一般不兼容J2EE的JMS限制。大多数情况下,我们还是使用DefaultMessageListenerContainer,跟MessageListenerContainer:SimpleMessageListenerContainer想比,它会动态的适应运行时的需求,并且能够参与外部的事务管理。它很好的平衡了JMS提供者要求低,先进功能如事务参与和兼容J2EE环境。
spring配置文件中添加:
<bean id="queueDestination" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg>
<value>sqlQueue</value>
</constructor-arg>
</bean>
<bean id="listenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="poolConnectionFactory" />
<property name="messageListener" ref="jmsQueueReceiver" />
<property name="destination" ref="queueDestination" />
</bean>
其中的jmsQueueReceiver代码如下:
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;
import org.springframework.stereotype.Component;
@Component("jmsQueueReceiver")
public class JmsQueueReceiver implements MessageListener
{
@Override
public void onMessage(Message messgae)
{
if(messgae instanceof TextMessage)
{
TextMessage textMessage = (TextMessage) messgae;
try
{
String text = textMessage.getText();
System.out.println("######################["+text+"]######################");
}
catch (JMSException e)
{
e.printStackTrace();
}
}
}
}
事务管理
Spring提供了一个JmsTransactionManager用于对JMS ConnectionFactory做事务管理。这将允许JMS应用利用Spring的事务管理特性。JmsTransactionManager在执行本地资源事务管理时将从指定的ConnectionFactory绑定一个ConnectionFactory/Session这样的配对到线程中。JmsTemplate会自动检测这样的事务资源,并对他们进行相应的操作。
在J2EE环境中,ConnectionFactory会池化Connection和Session,这样这些资源将会在整个事务中被有效地重复利用。在一个独立的环境中,使用Spring的SingleConnectionFactory时所有的事务将公用一个Connection,但是每个事务将保留自己独立的Session.
JmsTemplate可以利用JtaTransactionManager和能够进行分布式的JMS ConnectionFactory处理分布式事务。
在Spring整合JMS的应用中,如果我们要进行本地的事务管理的话非常简单,只需要在定义对于的消息监听容器时指定其sessionTransacted属性为true(默认为false):
<bean id="listenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory" />
<property name="messageListener" ref="jmsQueueReceiver" />
<property name="destination" ref="queueDestination" />
<property name="sessionTransacted" value="true"/>
</bean>
这样JMS在进行消息监听的时候就会进行事务控制,当在接收消息时监听器执行失败时JMS就会对接收到的消息进行回滚。这里需要注意的是对于其他操作如数据库等访问不属于该事务控制。
可以在JmsQueueReceiver中修改一下代码从而检测到发送异常时是否会进行事务回滚:
@Component("jmsQueueReceiver")
public class JmsQueueReceiver implements MessageListener
{
@Override
public void onMessage(Message messgae)
{
if(messgae instanceof TextMessage)
{
TextMessage textMessage = (TextMessage) messgae;
try
{
String text = textMessage.getText();
System.out.println("######################["+text+"]######################");
if(true)
{
throw new RuntimeException("Error");
}
}
catch (JMSException e)
{
e.printStackTrace();
}
}
}
}
你可以通过向Destination发送一条信息,通过JmsQueueReceiver处理后,发送异常进而事务混滚。可以通过http://10.10.195.187:8161/admin/queues.jsp查看相关信息(ip地址是博主的ActiveMQ服务器所在id,根据实际情况修改)。
如果想要接收消息和数据库访问处于同一事务中,那么我们就可以配置一个外部的事务管理同时配置一个支持外部事务管理的消息监听容器(如DefaultMessageListenerContainer)。要配置这样一个参与分布式事务管理的消息监听容器,我们可以配置一个JtaTransactionManager,当然底层的JMS ConnectionFactory需要能够支持分布式事务管理,并正确地注册我们的JtaTransactionManager。这样消息监听器进行消息接收和对应的数据库访问就会处于同一数据库控制下,当消息接收失败或数据库访问失败都会进行事务回滚操作。
<bean id="listenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory" />
<property name="messageListener" ref="jmsQueueReceiver" />
<property name="destination" ref="queueDestination" />
<property name="sessionTransacted" value="true"/>
<property name="transactionManager" ref="jtaTransactionManager"/>
</bean>
<bean id="jtaTransactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"/>
当给小时监听容器指定了transactionManager时,消息监听容器将忽略sessionTransacted的值。
到这里大概的Spring+ActiveMQ整合告一段落,所有代码经博主亲测,确保有效性及正确性。如有疑问,可在下方留言。
发表评论
-
复习:强迫线程顺序执行方式
2019-01-03 23:42 1566方法1: 三个线程,t1,t2,t3,如果一定要按顺序执行, ... -
(转)不错的前后端处理异常的方法
2019-01-02 23:16 2017前言 在 Web 开发中, 我们经常会需要处理各种异常, 这是 ... -
info q的极客时间大咖说等资料下载
2018-08-15 08:40 3463info q的极客时间大咖说等资料下载,还有不少思维导图 链 ... -
CXF 客户端超时时间设置(非Spring配置方式)
2018-07-03 22:38 2231import org.apache.cxf.endpoint. ... -
(转)synchronized关键字画像:正确打开方式
2018-06-14 09:25 489https://mp.weixin.qq.com/s/b3Sx ... -
CountDownLatch的例子
2018-06-13 14:10 683public class StatsDemo { ... -
两道面试题,带你解析Java类加载机制
2018-06-12 16:29 606https://mp.weixin.qq.com/s/YTa0 ... -
Spring中获取request的几种方法,及其线程安全性分析
2018-06-11 09:03 668https://mp.weixin.qq.com/s/KeFJ ... -
内部类小结
2018-06-06 10:25 432https://mp.weixin.qq.com/s/hErv ... -
JVM虚拟机小结1
2018-06-04 20:43 5381 jps -l //列出详细的类名和进程ID 2)jps ... -
windows下自带命令行工具查看CPU资源情况等
2018-06-04 12:53 3095微软提供了不少命令行 ... -
(收藏)深入分析Java的序列化与反序列化
2018-05-30 15:21 612https://mp.weixin.qq.com/s/T2Bn ... -
apache common包中的序列化工具
2018-05-30 09:10 1842什么是序列化 我们的 ... -
JAVA8 JVM的变化: 元空间(Metaspace)
2018-05-24 22:30 962本文将会分享至今为至我收集的关于永久代(Permanent G ... -
(转)服务器性能指标(一)——负载(Load)分析及问题排查
2018-05-21 21:03 1359原创: Hollis Hollis 负载 ... -
(转)对象复用
2018-05-20 15:27 856public class Student { priv ... -
mapreduce中入门中要注意的几点
2018-05-06 08:59 668在 mapreduce中,比如有如下的词: I love b ... -
HDFS的基本操作
2018-05-02 21:47 936-mkdir 在HDFS创建目录 ... -
一个不错的开源工具类,专门用来解析日志头部的,好用
2018-05-02 20:00 767一个不错的开源工具类,专门用来解析日志头部的,好用。 http ... -
介绍个不错的RESTFUL MOCK的工具wiremock
2018-04-27 21:02 1903介绍个不错的RESTFUL MOCK的工具wiremock,地 ...
相关推荐
标题"jms+spring+activeMq的例子serd和recevice"提到了三个关键术语:JMS(Java Message Service)、Spring框架和ActiveMQ。这表明我们将探讨一个结合了这三个技术的示例,其中"serd"可能是"server"的误拼,而...
【标题】"dubbo+spring+zookeeper整合案例详解" 【描述】该资源是一个全面的教程,涵盖了将Dubbo、Spring和Zookeeper整合到一起的实际操作步骤,包括完整的配置文件和必要的jar包。遗憾的是,它没有涉及Dubbo与...
在"轻量级Java ee企业应用实战struts2+sping+hibernate整合开发源码(3.9)"这个项目中,开发者可能已经完成了以下关键模块的搭建: 1. **配置文件**:包括struts2的struts.xml,Spring的applicationContext.xml,...
SSH(Struts、Spring、Hibernate)就是这样一个经典的轻量级Java开发栈,它整合了三个强大的开源框架,为开发者提供了高效且灵活的解决方案。《轻量级J2EE企业应用实践-tructs+spring+hibernate整合开发》09部分,很...
《轻量级J2EE企业应用实践:Struts+Spring+Hibernate整合开发》是一本深入讲解如何在实际项目中高效地使用这三个框架进行集成开发的书籍。这本书的核心内容是介绍如何将Struts作为表现层框架,Spring作为业务层管理...
《轻量级J2EE企业应用实践-tructs+spring+hibernate整合开发》是一部深入探讨Java企业级应用开发的教程,特别是针对轻量级框架的整合使用。本部分内容聚焦于系列教程的第七章,可能涉及的是这些框架在实际项目中的...
"Spring+Shiro 整合"意味着将这两个框架结合起来,以实现更高效、安全的Web应用开发。 首先,Spring 与 Shiro 的整合主要涉及以下几个方面: 1. **Shiro 的配置**:在 Spring 应用中引入 Shiro 需要在 Spring 配置...
"struts2+spring+mybatis整合jar(非常完整)"的标题意味着这个压缩包包含了整合这三个框架所需的所有库文件。在Java Web开发中,这样的整合能够实现各框架之间的无缝协作,例如,通过Spring管理Struts2的Action类,...
《轻量级J2EE企业应用实践:Struts+Spring+Hibernate整合开发》是一本深入讲解如何在J2EE环境中采用轻量级框架进行企业级应用开发的书籍。SSH(Struts、Spring、Hibernate)是Java开发中的经典组合,它们分别负责MVC...
《轻量级J2EE企业应用实践-tructs+spring+hibernate整合开发》是一部深入探讨J2EE开发的经典教程,重点在于如何利用Struts、Spring和Hibernate这三大框架进行高效、轻量级的企业应用构建。这三者合称为SSH(Struts-...
### Struts+Spring+Hibernate整合入门详解 #### 一、基本概念 - **Struts**:作为基于MVC(Model-View-Controller)模式的Web应用框架,Struts已经成为了一个非常重要的工具。随着项目的演进,Struts 1 和 WebWork...
《轻量级J2EE企业应用实践-tructs+spring+hibernate整合开发》是一部深入探讨如何在J2EE环境中使用轻量级框架进行高效开发的教程。本部分主要聚焦于第04章节的内容,这通常涉及到这些框架的集成与实际应用。以下是...
本章节《轻量级J2EE企业应用实践-tructs+spring+hibernate整合开发》08,将深入探讨如何将Struts、Spring和Hibernate这三大主流框架集成,以构建高效的企业级应用程序。 Struts是Apache软件基金会的一个开源MVC框架...
标题 "dubbo+spring+zookeeper整合例子完整版(包括步骤文档和所有jar).zip" 提供的是一个关于如何集成Dubbo、Spring和Zookeeper的实战示例,这是一套常见的微服务架构组合。Dubbo是一个高性能、轻量级的开源Java RPC...
《轻量级Java EE企业应用实战:Struts2+Spring+Hibernate整合开发源码解析》 在Java EE领域,轻量级框架的整合是提升开发效率、优化代码结构的重要手段。Struts2、Spring和Hibernate这三大框架的联合使用,构建了...
总的来说,《轻量级J2EE企业应用实践》第二章的内容将涵盖Struts、Spring和Hibernate的基本概念、配置方法、整合步骤以及实际应用技巧,对于想要掌握J2EE轻量级开发的读者来说,是非常宝贵的学习资料。通过阅读和...
《轻量级J2EE企业应用实践》一书聚焦于Tructs、Spring和Hibernate的整合开发,这三者是Java领域中极为重要的框架,它们的结合为开发高效、可维护的企业级应用提供了强大支持。在本节"03下"中,我们将深入探讨这些...
struts+sping+hibernate
Spring作为一个轻量级的框架,有很多的拓展功能,最主要的我们一般项目使用的就是IOC和AOP。 SpringMVC是Spring实现的一个Web层,相当于Struts的框架,但是比Struts更加灵活和强大! Mybatis是 一个持久层的框架,在...
struts+sping+hibernate