04.ActiveMQ与Spring JMS整合
1.SpringJMS核心接口介绍
// send - 发送一个消息,使用消息创建接口MessageCreator
publicvoid send(MessageCreator messageCreator)
publicvoid send(finalDestination destination,finalMessageCreator messageCreator)
publicvoid send(finalString destinationName,finalMessageCreator messageCreator)
// sendAndReceive - 发送并接收消息
publicMessage sendAndReceive(MessageCreator messageCreator)
publicMessage sendAndReceive(finalDestination destination,finalMessageCreator messageCreator)
publicMessage sendAndReceive(finalString destinationName,finalMessageCreator messageCreator)
// convertAndSend - 使用MessageConverter接口转换消息,先将对象转换成消息再发送消息。与之对应的是receiveAndConvert方法
publicvoid convertAndSend(Object message)throwsJmsException
publicvoid convertAndSend(Destination destination,finalObject message)
publicvoid convertAndSend(String destinationName,finalObject message)
publicvoid convertAndSend(Object message,MessagePostProcessor postProcessor)
publicvoid convertAndSend(Destination destination,finalObject message,finalMessagePostProcessor postProcessor)
publicvoid convertAndSend(String destinationName,finalObject message,finalMessagePostProcessor postProcessor)
// receive - 接收消息
publicMessage receive()
publicMessage receive(Destination destination)
publicMessage receive(String destinationName)
// receiveSelected - 接收消息,并过滤消息
publicMessage receiveSelected(String messageSelector)
publicMessage receiveSelected(finalDestination destination,finalString messageSelector)
publicMessage receiveSelected(finalString destinationName,finalString messageSelector)
// receiveAndConvert - 接收消息,并使用MessageConverter接口转换消息,把一个消息转换成一个对象
publicObject receiveAndConvert()
publicObject receiveAndConvert(Destination destination)
publicObject receiveAndConvert(String destinationName)
// receiveSelectedAndConvert - 接收消息,并使用消息过滤和消息转换
publicObject receiveSelectedAndConvert(String messageSelector)
publicObject receiveSelectedAndConvert(Destination destination,String messageSelector)
publicObject receiveSelectedAndConvert(String destinationName,String messageSelector)
// browse - 浏览消息
public<T> T browse(BrowserCallback<T> action)
public<T> T browse(Queue queue,BrowserCallback<T> action)
public<T> T browse(String queueName,BrowserCallback<T> action)
// browseSelected - 浏览消息,并使用过滤
public<T> T browseSelected(String messageSelector,BrowserCallback<T> action)
public<T> T browseSelected(finalQueue queue,finalString messageSelector,finalBrowserCallback<T> action)
public<T> T browseSelected(finalString queueName,finalString messageSelector,finalBrowserCallback<T> action)
// execute - 执行SessionCallback、ProducerCallback、BrowserCallback回调接口,并得到回调接口返回值
public<T> T execute(SessionCallback<T> action)
public<T> T execute(SessionCallback<T> action,boolean startConnection)
public<T> T execute(ProducerCallback<T> action)
public<T> T execute(finalDestination destination,finalProducerCallback<T> action)
public<T> T execute(finalDestination destination,finalProducerCallback<T> action)
- PooledConnectionFactory:会缓存connection,session和productor,不会缓存consumer。因此只适合于生产者发送消息。
- SingleConnectionFactory:对于建立JMS服务器链接的请求会一直返回同一个Connection,并且会忽略Connection的close方法调用(包括调用createConnection()得到的Connection)
- CachingConnectionFactory:继承了SingleConnectionFactory,所以它拥有SingleConnectionFactory的所有功能,同时它还新增了缓存功能,它可以缓存Session、MessageProducer和MessageConsumer。
- MessageCreator -- 消息创建接口,发送消息时需要使用此接口创建消息
- SessionCallback -- 使用JMS Session时的回调接口
- ProducerCallback -- 使用JMS Session和MessageProducer时的回调接口
- BrowserCallback -- 使用JMS Session和QueueBrowser时的回调接口
- MessageListener -- 消息监听器接口,注解@JmsListener与其功能相似
- ListenerContainer -- 消息侦听器容器接口,实现有SimpleMessageListenerContainer、DefaultMessageListenerContainer
- MessageConverter -- 消息转换接口,用于JMS消息到Java对象之间的转换
2.消息监听器
publicclassQueueMessageListenerimplementsMessageListener
{
@Override
publicvoid onMessage(Message message)
{
try
{
if(message instanceofTextMessage)
{
TextMessage tm =(TextMessage) message;
System.out.println("监听消息:"+ tm.getText());
}
else
{
System.out.println("消息类型:"+ message.getClass());
}
}
catch(JMSException e)
{
e.printStackTrace();
}
}
}
publicclassQueueSessionAwareMessageListenerimplementsSessionAwareMessageListener<TextMessage>
{
/** 回复消息的目的地 */
privateDestination destination;
@Override
publicvoid onMessage(TextMessage message,Session session)throwsJMSException
{
System.out.println("监听消息内容:"+ message.getText());
MessageProducer messageProducer = session.createProducer(destination);
TextMessage replyMessage = session.createTextMessage("已收到消息:"+ message.getJMSMessageID());
messageProducer.send(replyMessage);
}
publicDestination getDestination()
{
return destination;
}
publicvoid setDestination(Destination destination)
{
this.destination = destination;
}
}
- TextMessage转换为String对象
- BytesMessage转换为byte数组
- MapMessage转换为Map对象
- ObjectMessage转换为对应的Serializable对象
<!--消息监听适配器-->
<bean id="messageListenerAdapter"class="org.springframework.jms.listener.adapter.MessageListenerAdapter">
<!--通过构造函数指定消息处理器-->
<constructor-arg>
<bean id="readerMessage"class="com.test.ReaderMessage"/>
</constructor-arg>
<!--指定消息处理器类处理消息的方法-->
<property name="defaultListenerMethod" value="receiveMessage"/>
<!--通过delegate属性指定消息处理器-->
<property name="delegate">
<bean id="readerMessage"class="com.test.ReaderMessage"/>
</property>
</bean>
publicclassMessageListenerByAdapter
{
publicvoid handleMessage(String message)
{
System.out.println("handleMessage方法处理消息,消息内容是:"+ message);
}
publicvoid receiveMessage(String message)
{
System.out.println("receiveMessage方法处理消息,消息内容是:"+ message);
}
}
- 第一,可以通过发送的Message的setJMSReplyTo方法指定该消息对应的回复消息的目的地。这需要生产者发送消息之前调用setJMSReplyTo方法。
- 第二,通过MessageListenerAdapter的defaultResponseDestination属性来指定。
- <bean id="jmsContainer"class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<!--设置连接工厂-->
<property name="connectionFactory" ref="connectionFactory"/>
<!--设置监听地址-->
<property name="destination" ref="queueDestination"/>
<!--设置消息监听处理器,可以是以上三种-->
<property name="messageListener" ref="queueMessageListener"/>
</bean>
- SimpleMessageListenerContainer:这个消息侦听容器是三种中最简单的。它在启动时创建一个会话session和消费者Consumer,并且会使用标准的JMS MessageConsumer.setMessageListener()方法注册监听器让JMS提供者调用监听器的回调函数。它不会动态的适应运行时需要和参与外部的事务管理。兼容性方面,它非常接近于独立的JMS规范,但一般不兼容Java EE的JMS限制。
- DefaultMessageListenerContainer:这个消息侦听器使用的最多。跟SimpleMessageListenerContainer相比,DefaultMessageListenerContainer会动态的适应运行时需要,并且能够参与外部的事务管理。它很好的平衡了对JMS提供者要求低、先进功能如事务参与和兼容Java EE环境。
- ServerSessionMessageListenerContainer:这个监听器容器利用JMS ServerSessionPool SPI动态管理JMS Session。使用者各种消息监听器可以获得运行时动态调优功能,但是这也要求JMS提供者支持ServerSessionPool SPI。如果不需要运行时性能调整,请使用 DefaultMessageListenerContainer 或 SimpleMessageListenerContainer。
3.ActiveMQ与SpringJMS整合示例
<?xml version="1.0" encoding="UTF-8"?>
<beansxmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jms="http://www.springframework.org/schema/jms"
xsi:schemaLocation="
http://www.springframework.org/schema/jms
http://www.springframework.org/schema/jms/spring-jms-4.0.xsd
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"
default-lazy-init="false">
<!-- 配置JMS连接工厂 -->
<beanid="connectionFactory"class="org.apache.activemq.ActiveMQConnectionFactory">
<propertyname="brokerURL"value="failover:(tcp://localhost:61616)"/>
</bean>
<!-- ActiveMQ连接池配置,ActiveMQ实现 -->
<!--
<bean id="pooledConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory" destroy-method="stop">
<property name="connectionFactory" ref="connectionFactory" />
</bean>
-->
<!-- ActiveMQ连接池配置,SpingJMS实现 -->
<beanid="cachingConnectionFactory"class="org.springframework.jms.connection.CachingConnectionFactory">
<propertyname="targetConnectionFactory"ref="connectionFactory"/>
<!-- Session缓存数量,这里属性也可以直接在这里配置 -->
<propertyname="sessionCacheSize"value="100"/>
</bean>
<!-- 消息队列01 -->
<beanid="queueDestination01"class="org.apache.activemq.command.ActiveMQQueue">
<!-- 设置消息队列的名字 -->
<constructor-arg>
<value>spring-jms-queue01</value>
</constructor-arg>
</bean>
<!-- 消息队列02 -->
<beanid="queueDestination02"class="org.apache.activemq.command.ActiveMQQueue">
<!-- 设置消息队列的名字 -->
<constructor-arg>
<value>spring-jms-queue02</value>
</constructor-arg>
</bean>
<!-- 配置JMS模板,Spring提供的JMS工具类,它发送、接收消息。 -->
<beanid="jmsTemplate"class="org.springframework.jms.core.JmsTemplate">
<propertyname="connectionFactory"ref="cachingConnectionFactory"/>
<propertyname="defaultDestination"ref="queueDestination01"/>
<propertyname="receiveTimeout"value="10000"/>
</bean>
<!-- 消息监听容器(Queue),配置连接工厂,监听的队列是spring-jms-queue02,监听器是上面定义的监听器 -->
<beanid="jmsContainer"class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<propertyname="connectionFactory"ref="cachingConnectionFactory"/>
<propertyname="destination"ref="queueDestination02"/>
<propertyname="messageListener">
<beanid="queueMessageListener"class="spring.QueueMessageListener"/>
</property>
</bean>
</beans>
publicclassQueueMessageListenerimplementsMessageListener
{
@Override
publicvoid onMessage(Message message)
{
try
{
if(message instanceofTextMessage)
{
TextMessage tm =(TextMessage) message;
System.out.println("监听消息:"+ tm.getText());
}
else
{
System.out.println("消息类型:"+ message.getClass());
}
}
catch(JMSException e)
{
e.printStackTrace();
}
}
}
/** 自定义消息创建器 */
publicclassMyMessageCreatorimplementsMessageCreator
{
privateString messageStr;
publicMyMessageCreator(String messageStr)
{
this.messageStr = messageStr;
}
@Override
publicMessage createMessage(Session session)throwsJMSException
{
return session.createTextMessage(messageStr);
}
}
publicstaticvoid main(String[] args)throwsException
{
ClassPathXmlApplicationContext applicationContext =newClassPathXmlApplicationContext("spring-context-jms.xml");
// 得到消息队列
Destination queueDestination01 = applicationContext.getBean("queueDestination01",Destination.class);
Destination queueDestination02 = applicationContext.getBean("queueDestination02",Destination.class);
// Spring JMS操作模版
JmsTemplate jmsTemplate = applicationContext.getBean("jmsTemplate",JmsTemplate.class);
// 发送消息
jmsTemplate.send(queueDestination01,newMyMessageCreator("测试消息001"));
jmsTemplate.send(queueDestination01,newMyMessageCreator("测试消息002"));
jmsTemplate.send(queueDestination02,newMyMessageCreator("测试消息003"));
jmsTemplate.send(queueDestination02,newMyMessageCreator("测试消息004"));
//接收消息
TextMessage textMessage =(TextMessage) jmsTemplate.receive(queueDestination01);
System.out.println(textMessage.getText());
textMessage =(TextMessage) jmsTemplate.receive(queueDestination01);
System.out.println(textMessage.getText());
applicationContext.close();
System.out.println("OK!");
}
监听消息:测试消息003
监听消息:测试消息004
测试消息001
测试消息002
OK!
4.消息转换MessageConverter
publicclassUserimplementsSerializable
{
privatestaticfinallong serialVersionUID =1L;
privateString name;
privateint age;
privateboolean sex;
......
}
publicclassUserMessageConverterimplementsMessageConverter
{
privateObjectMapper mapper =newObjectMapper();
@Override
publicMessage toMessage(Object object,Session session)throwsJMSException,MessageConversionException
{
String json =null;
try
{
json = mapper.writeValueAsString(object);
}
catch(JsonProcessingException e)
{
e.printStackTrace();
}
System.out.println("toMessage : "+ json);
return session.createTextMessage(json);
}
@Override
publicObject fromMessage(Message message)throwsJMSException,MessageConversionException
{
String json =((TextMessage) message).getText();
Object object =null;
try
{
object = mapper.readValue(json,User.class);
}
catch(Exception e)
{
e.printStackTrace();
}
System.out.println("fromMessage : "+ object);
return object;
}
}
- org.springframework.jms.support.converter.SimpleMessageConverter
- org.springframework.jms.support.converter.MessagingMessageConverter
- org.springframework.jms.support.converter.MarshallingMessageConverter
- org.springframework.jms.support.converter.MappingJackson2MessageConverter
<!-- 配置JMS模板,Spring提供的JMS工具类,它发送、接收消息。 -->
<beanid="jmsTemplate"class="org.springframework.jms.core.JmsTemplate">
<propertyname="connectionFactory"ref="cachingConnectionFactory"/>
<propertyname="defaultDestination"ref="queueDestination01"/>
<propertyname="receiveTimeout"value="10000"/>
<propertyname="messageConverter">
<beanid="userMessageConverter"class="spring.UserMessageConverter"/>
</property>
</bean>
User user=newUser("危常焕",20,true);
// 发送消息
jmsTemplate.convertAndSend(user);
//接收消息
Object object = jmsTemplate.receiveAndConvert();
System.out.println(object);
toMessage :{"name":"危常焕","age":20,"sex":true}
fromMessage :User[name=危常焕, age=20, sex=true]
User[name=危常焕, age=20, sex=true]
OK!
5.事务管理JmsTransactionManager
04.ActiveMQ与Spring JMS整合的更多相关文章
- activeMQ入门+spring boot整合activeMQ
最近想要学习MOM(消息中间件:Message Oriented Middleware),就从比较基础的activeMQ学起,rabbitMQ.zeroMQ.rocketMQ.Kafka等后续再去学习 ...
- ActiveMQ与Spring / SpringBoot 整合(四)
1. 对 Spring 的整合 1.1 所需jar 包 <!-- activeMQ jms 的支持 --> <dependency> <groupId>org.sp ...
- 【ActiveMQ】Spring Jms集成ActiveMQ学习记录
Spring Jms集成ActiveMQ学习记录. 引入依赖包 无论生产者还是消费者均引入这些包: <properties> <spring.version>3.0.5.REL ...
- Spring整合ActiveMQ:spring+JMS+ActiveMQ+Tomcat
一.目录结构 相关jar包 二.关键配置activmq.xml <?xml version="1.0" encoding="UTF-8"?> < ...
- activeMQ和spring的整合
http://www.cnblogs.com/shuai-server/p/8966299.html 这篇博客中介绍了activemq传递消息的两种方式,今天分享的是activemq框架和sprin ...
- Spring JMS ActiveMQ整合(转)
转载自:http://my.oschina.net/xiaoxishan/blog/381209#comment-list ActiveMQ学习笔记(四)http://my.oschina.net/x ...
- spring boot整合activemq消息中间件
spring boot整合activemq消息中间件 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi ...
- 使用注解和xml两种方式整合Activemq与spring(gradle工程)
一.新建gradle工程 1.1 使用intellij新建gradle工程步骤省略 二.导入依赖,配置build.gradle plugins { id 'java' } group 'com.bdh ...
- ActiveMQ 笔记(四)Spring\SpringBoot 整合 Activemq
个人博客网:https://wushaopei.github.io/ (你想要这里多有) 一.Spring 整合Activemq 1.所需jar包 <dependencies> &l ...
随机推荐
- C# 属性事件一些设置说明
大致列举一些常用的属性或事件的一些修饰 用法类似,主要是对属性的进一步设置 [Browsable(true)] public bool Enable {get;set;} 顺便说一下事件的应用: pu ...
- 截取scrollview的滑动事件,传递给子控件
重写一个ScrollView public class MyScrollView extends ScrollView{ public MyScrollView(Context context, At ...
- 五步让你玩转CocoaPods
1 安装和升级 $ sudo gem install cocoapods $ pod setup 2 更换为taobao的源 $ gem sources -r https://rubygems.or ...
- vs2008 调试时不会命中断点,源代码与原始版本不同,解决办法
当前不会命中断点,源代码与原始版本不同,解决办法 1.应该是自己一行里写的代码太长了 格式化一下 或者 换下行 2. VC直接把整个文件格式化了一次,断点就可以用了 菜单:编辑-〉高级-〉设置选定内容 ...
- 哈希----字符串----time33
//此处只是获得了字符串的hash值,但是该如何散列到hash表中呢?哪个算法会好些?! 1 //在处理以字符串为键值的哈希时,times33哈希算法有着极快的计算效率和很好的哈希分布 //小写英文单 ...
- [转]JVM性能调优监控工具
http://my.oschina.net/feichexia/blog/196575?p=1#comments JDK本身提供了很多方便的JVM性能调优监控工具,除了集成式的VisualVM和jCo ...
- 使用ADO实现BLOB数据的存取 -- ADO开发实践之二
使用ADO实现BLOB数据的存取 -- ADO开发实践之二 http://www.360doc.com/content/11/0113/16/4780948_86256633.shtml 一.前言 在 ...
- WinSock1.1和WinSock2.0
网络编程很重要,说到网络编程就不得不提Socket编程. Windows提供了Windows Socket API(简称WSA),WinSock,目前有两个版本:WinSock1.1 and WinS ...
- 记录下DynamicXml和HtmlDocument 使用方式
之前解析都是XmlDocument.Load 而现在可以利用DynamicXml生成Dynamic对象实现强类型操作,很好用. /// <summary> /// 根据Xml路径动态解析成 ...
- 关于NoSQL与SQL的区别
简单说来:sql是关系型数据库的结构化查询语言,而nosql,一般代指菲关系型数据库,sql语句就不能用来,不过有些有leisql的查询语言,且nosql数据库没有统一的查询语言. 相关参考文章阅读: ...