04.ActiveMQ与Spring JMS整合
1.SpringJMS核心接口介绍
// send - 发送一个消息,使用消息创建接口MessageCreatorpublicvoid 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)throwsJmsExceptionpublicvoid 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{@Overridepublicvoid 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;@Overridepublicvoid 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/jmshttp://www.springframework.org/schema/jms/spring-jms-4.0.xsdhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-4.0.xsdhttp://www.springframework.org/schema/contexthttp://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{@Overridepublicvoid 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;}@OverridepublicMessage 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测试消息002OK!
4.消息转换MessageConverter
publicclassUserimplementsSerializable{privatestaticfinallong serialVersionUID =1L;privateString name;privateint age;privateboolean sex;......}
publicclassUserMessageConverterimplementsMessageConverter{privateObjectMapper mapper =newObjectMapper();@OverridepublicMessage 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);}@OverridepublicObject 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 ...
随机推荐
- erlang随机数问题
一.计算机的随机数的老问题,伪随机数. random:seed() random:uniform(N) 如果seed是相同的,则第M次执行 random:uniform(N) .M.N相同,则得到的随 ...
- 【Java面试题】39 Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==还是equals()? 它们有何区别?
1.什么是Set?(what) Set是Collection容器的一个子接口,它不允许出现重复元素,当然也只允许有一个null对象. 2.如何来区分重复与否呢?(how) “ 用 iterator() ...
- Linux 快速删除大量小文件方法
进行以下两步操作即可: 1.第一步:创建空的文件夹: mkdir /tmp/blank 2.第二步:执行以下命令:rsync --delete-before -d /tmp/blank/ /home ...
- Adobe Acrobat 不能打开在线pdf。Adobe Acrobat 应用程序正在被终止,因为内存错误
Adobe Acrobat 应用程序正在被终止,因为内存错误. Adobe Acrobat 不能打开在线pdf. 当出现上面两种错误时. 原因可能是Acrobat的更新有问题. 解决方法:打开C:\D ...
- Oracle居然把Java EE的未来押在Rest API上了
然而Lehman并不赞同Rahman对Java EE 9的说法,所以他重申Oracle暂时专注于Java EE 8."我们正在倾全力推出EE 8,现在这是我们主要的关注点," ...
- 浅谈无缓存I/O操作和标准I/O文件操作差别
首先,先略微了解系统调用的概念: 系统调用,英文名system call,每一个操作系统都在内核里有一些内建的函数库,这些函数能够用来完毕一些系统系统调用把应用程序的请求传给内核,调用对 ...
- vertica时间计算SQL语句实例:统计一天内登录的用户
SQL语句实例: select count(id) as num from public.user where cast((CURRENT_TIMESTAMP-login_timed) day as ...
- hadoop程序MapReduce之average
需求:求多门课程的平均值. 样板:math.txt zhangsan 90 lisi 88 wanghua 80 china.txt zhangsan 80lisi 90wanghua 88 输出:z ...
- 当新增页面和编辑页面使用同一jsp时
<c:if test="${type eq '1'}"><title>新增页面</title></c:if> <c:if te ...
- Mybaits中的update
<update id="update" parameterType="Currency"> UPDATE YZ_SECURITIES_CURRENC ...