ActiveMQ——4.Spring-JmsTemplate之发送与接收
来源:互联网 发布:淘宝虚拟物品仅退款 编辑:程序博客网 时间:2024/05/17 05:17
发送
概述
JmsTemplate提供了3组*3,共计9个发送用的方法。
发送的方法有3组:
- 基本的发送
- 转换并发送
- 转换、后处理再发送
必需的资源
必需的资源有:
- javax.jms.ConnectionFactory
ConnectionFactory是客户端编程的开始,由它依次获取Connection、Session、Message、MessageProducer或MessageConsumer,从而做好了发送或接收的准备。 - javax.jms.Destination
Destination是发送的目的地,或者接收的源
实际上,我们提供了上述的资源之后,我们就是做了这样的指令:让JmsTemplate连接到Destination,从我们提供的ConnectionFactory中获取连接资源。
1.ConnectionFactory资源
我们如何提供ConnectionFactory给JmsTemplate?凭借JmsTemplete提供的构造器或setter方法:
- public JmsTemplate(ConnectionFactory connectionFactory)
- public void setConnectionFactory(ConnectionFactory connectionFactory)
# 继承自org.springframework.jms.support.JmsAccessor
2.Destination资源
我们如何提供Destination给JmsTemplate?
我们有两个机会做这件事,第一次是在初始化的时候提供一个默认的Destination,第二次是在发送的时候提供一个明确的Destination。相关的方法:
- public void setDefaultDestination(Destination destination)
设置默认的Destination - public void send(Destination destination, MessageCreator messageCreator)
将消息发送到指定的Destination
MessageCreator接口用来提供创建消息的回调方法,后面再讲。
JmsTemplate还提供了另一种获取Destination的方式:基于Destination解析器、Destination类型、Destination名字的获取。你可以使用下面的代码来指定解析器、Destination类型:
// jt is instance of JmsTemplatejt.setDestinationResolver(new DynamicDestinationResolver()); // set Destination解析器jt.setPubSubDomain(false); // set Destinantion类型
Destination解析器要实现org.springframework.jms.support.destination.DestinationResolver接口。解析器有默认的值,就是DynamicDestinationResolver,除非你要使用其他的解析器,否则不必调用setDestinationResolver。所以,第2行代码是多余的。
Destination类型有2个:false-Queue类型,true-Topic类型;默认为false。所以,第3行代码是多余的。
设置了解析器、类型,或者直接使用默认的值,之后,就可以设置destination的name。JmsTemplate提供了两个方法:
- public void setDefaultDestinationName(String destinationName)
设置defaultDestination。这个方法和setDefaultDestination(Destination destination)做同样的事情,只是这个方法依赖于解析器和类型。 - public void send(String destinationName, MessageCreator messageCreator)
将消息发送到指定的Destination。这个方法和send(Destination destination, MessageCreator messageCreator)做同样的事情,只是这个方法依赖于解析器和类型。
P.S.如何根据destinationName创建Destination实例?
javax.jms.Session提供了两个方法,分别创建两种类型的Destination:
- Queue createQueue(java.lang.String queueName)
根据name创建Queue类型的Destination - Topic createTopic(java.lang.String topicName)
根据name创建Topic类型的Destination
我们看下DynamicDestinationResolver的源码:
public class DynamicDestinationResolver implements DestinationResolver { @Override public Destination resolveDestinationName(Session session, String destinationName, boolean pubSubDomain) throws JMSException { Assert.notNull(session, "Session must not be null"); Assert.notNull(destinationName, "Destination name must not be null"); if (pubSubDomain) { return resolveTopic(session, destinationName); } else { return resolveQueue(session, destinationName); } } protected Topic resolveTopic(Session session, String topicName) throws JMSException { return session.createTopic(topicName); } protected Queue resolveQueue(Session session, String queueName) throws JMSException { return session.createQueue(queueName); }}根据这份源码,可以帮助理解pubSubDomain的机制,以及将JMS的api和Spring的Destination解析器这两个知识点连接起来。
1.基本的发送方法
在前文我们已经接触了两个,它们都是在发送的同时指定Destination。现把它们和第3种一起介绍:
- public void send(Destination destination, MessageCreator messageCreator)
将消息发送到指定的Destination - public void send(String destinationName, MessageCreator messageCreator)
将消息发送到指定的Destination。这个方法和send(Destination destination, MessageCreator messageCreator)做同样的事情,只是这个方法依赖于解析器和类型。 - public void send(MessageCreator messageCreator)
将消息发送到defaultDestination。
这个方法要求提前设置defaultDestination,你可以调用setDefaultDestination(Destination destination)或者setDefaultDestinationName(String destinationName)来满足这个前提。
在3个基本的发送方法中,都使用MessageCreator来创建消息。
使用MessageCreator创建消息
jms中的Message,是以接口javax.jms.Message为首的接口家族,这个家族的图谱是这样的:
javax.jms.Message
|---- BytesMessage
|---- MapMessage
|---- ObjectMessage
|---- StreamMessage
|---- TextMessage
JMS将Message细分为5种类型,并在javax.jms.Session接口中分别定义了创建上述Message的多个方法,通常以create*Message为名,返回对应的Message类型。
在JMS的api中,只有javax.jms.Session能创建消息。
所以在Spring中,如果我们要创建Message,就要有Session。但是我们只有现成的ConnectionFactory,我们不应该走一遍从ConnectionFactory到Session的路,否则我们也不需要JmsTemplate帮我们发送了,因为剩下的工作也没多少了——关键是我们并没有从JMS的API中解脱出来。
所以有了MessageCreator的接口,它定义了一个回调的方法:
- Message createMessage(Session session)
只要我们把MessageCreator的实例传给JmsTemplate,它就会在合适的时候调用这个方法,并发送返回的消息。
下面给一个例子:
jt.send(DESTINATION_NAME, new MessageCreator() { public Message createMessage(Session session) throws JMSException { String text = "A test for MessageCreator."; Message message = session.createTextMessage(text); return message; }});
2.转换并发送的方法
我们需要将数据装进JMS的Message,然后再发送。JMS的Message有5种具体的类型,不同的类型适合装载不同的数据。如果你不想做这段工作,而是希望能直接把数据丢给谁,然后由它来封装成Message——你只想准备数据,然后发送。那么接下来要介绍的方法,正适合你。
Spring为转换定义了一个接口:org.springframework.jms.support.converter.MessageConverter,这个接口定义了下面的两个方法:
- Message toMessage(Object object, Session session)
发送时用到 - Object fromMessage(Message message)
接收时用到
一般情况下,我们既不需要为MessageConverter提供实现,也不需要面向MessageConverter进行编程,所以我们实在没有必要关注上面的两个方法,扫一眼,有个大概的印象就够了。
说回JmsTemplate,它定义了下面的方法来设置Converter:
- public void setMessageConverter(MessageConverter messageConverter)
而且在初始化的时候,会自动赋值一个SimpleMessageConverter类型的实例,所以我们甚至也不需要关心setMessageConverter方法了。
说了这不多,总结一下,如果要用到转换,我们需要多做什么工作?答案是不需要!
下面是具有转换功能的发送的方法,与基本的发送的方法进行对比:
转换发送基本发送
- public void convertAndSend(Destination destination, Object message)
将message转换成JMS的Message,并发送到指定的Destination - public void convertAndSend(String destinationName, Object message)
将message转换成JMS的Message,并发送到指定的Destination。 - public void convertAndSend(Object message)
将message转换成JMS的Message,并发送到defaultDestination。
- public void send(Destination destination, MessageCreator messageCreator)
将消息发送到指定的Destination - public void send(String destinationName, MessageCreator messageCreator)
将消息发送到指定的Destination。 - public void send(MessageCreator messageCreator)
将消息发送到defaultDestination。
这两个系列的方法相似度很高,只是在创建消息的问题上有不同的处理:转换发送隐藏了消息的创建,基本发送需要实现MessageCreator接口来创建消息。
接下来是一个demo,我们将上面的demo也拿下来,做一个对比:
String message = "a message for test convertAndSend.";jt.convertAndSend(DESTINATION_NAME, message);
jt.send(DESTINATION_NAME, new MessageCreator() { public Message createMessage(Session session) throws JMSException { String text = "A test for MessageCreator."; Message message = session.createTextMessage(text); return message; }});
3.转换、后处理再发送的方法
javax.jms.Message定义了很多的方法用来为消息添加头部信息或属性。但是如果我们要用转换并发送的方法,我们就接触不到Message类型的消息了,自然也无法为其添加任何信息。JmsTemplate提供了另一套发送的方法,允许我们使用自动转换,还允许我们能接触到转换后的消息,以便我们能做些什么。之后我们会返回处理后的Message,交给JmsTemplate发送。
Spring定义了org.springframework.jms.core.MessagePostProcessor接口来做后处理的事,它定义了一个唯一的方法:
- Message postProcessMessage(Message message)
对消息进行处理,并返回处理后的消息
让我们来看看这些方法,并与前文介绍的方法对比:
转换、后处理、发送转换、发送
- public void convertAndSend(Destination destination, Object message, MessagePostProcessor postProcessor)
- public void convertAndSend(String destinationName, Object message, MessagePostProcessor postProcessor)
- public void convertAndSend(Object message, MessagePostProcessor postProcessor)
- public void convertAndSend(Destination destination, Object message)
将message转换成JMS的Message,并发送到指定的Destination - public void convertAndSend(String destinationName, Object message)
将message转换成JMS的Message,并发送到指定的Destination。 - public void convertAndSend(Object message)
将message转换成JMS的Message,并发送到defaultDestination。
再来看看两个demo的对比:
转换、后处理、发送1 String message = "a message for test convertProcessAndSend.";2 jt.convertAndSend(DESTINATION_NAME, message,3 new MessagePostProcessor() {4 public Message postProcessMessage(Message message)5 throws JMSException {6 message.setIntProperty("order", 1);7 return message;8 }9 });
1 String message = "a message for test convertAndSend.";2 jt.convertAndSend(DESTINATION_NAME, message);
接收
概要
JmsTemplate提供了4组*3,共计12个接收用的方法。
JmsTemplate接收所需要的资源ConnectionFactory和Destination,和发送是一致的。
接收的方法有4组:
- 基本的接收
- 接收并转换
- 带有选择器的接收
- 选择接收并转换
1.基本的接收方法
JmsTemplate提供了3个基本的接收方法,与发送的方法进行对比:
接收发送
- public Message receive(Destination destination)
从指定的Destination接收消息并返回 - public Message receive(String destinationName)
从指定的Destination接收消息并返回。 - public Message receive()
从默认的Destination接收消息并返回。
- public void send(Destination destination, MessageCreator messageCreator)
将消息发送到指定的Destination - public void send(String destinationName, MessageCreator messageCreator)
将消息发送到指定的Destination。 - public void send(MessageCreator messageCreator)
将消息发送到defaultDestination。
接收到消息之后,需要对消息进行转换,再提取消息中的数据:
Message message = jt.receive(DESTINATION_NAME); // convertif (message != null && message instanceof TextMessage) { String text = ( (TextMessage) message ).getText(); System.out.println(text);}
2.接收并转换的方法
与转换并发送的方法相对应,接收的时候也有接收并转换的方法:
- public Object receiveAndConvert()
参考public Message receive(),在此基础上做了转换。 - public Object receiveAndConvert(Destination destination)
参考public Message receive(Destination destination),在此基础上做了转换。 - public Object receiveAndConvert(String destinationName)
参考public Message receive(String destinationName),在此基础上做了转换。
下面给出使用的示例,并把上面的示例也拿过来,做一下比较:
convertusual
1 Object data = jt.receiveAndConvert(DESTINATION_NAME);2 3 if (data != null && data instanceof String) {4 System.out.println(data);5 }
1 Message message = jt.receive(DESTINATION_NAME);2 3 // convert4 if (message != null && message instanceof TextMessage) {5 String text = ( (TextMessage) message ).getText();6 System.out.println(text);7 }
至少,我们不用再考虑收到的Message具体是哪一种类型的。
3.带有选择器的接收方法
到目前为止,我们介绍的接收会无差别接收指定的Destination中的消息。如果我们只想接收其中的一部分——基于一个筛选的条件,满足条件的消息快到碗里来,不满足的就留在锅里吧。这种“挑食”的行为就是通过选择器来实现的。
在消息的接收方式以及选择器中,我们已经介绍了选择器是什么一回事,并给出了基于JMS API的demo;这里我们直接列出要说的三个方法吧:
- public Message receiveSelected(String messageSelector)
参考public Message receive(),只是加入了筛选条件。 - public Message receiveSelected(Destination destination, String messageSelector)
参考public Message receive(Destination destination),只是加入了筛选条件 - public Message receiveSelected(String destinationName, String messageSelector)
参考public Message receive(String destinationName),只是加入了筛选条件
然后,再给一个demo:
发送接收
1 String message = "a message for test convertProcessAndSend."; 2 jt.convertAndSend(DESTINATION_NAME, message, 3 new MessagePostProcessor() { 4 5 public Message postProcessMessage(Message message) 6 throws JMSException { 7 message.setIntProperty("order", 1); 8 return message; 9 }10 });
1 jt.setReceiveTimeout(3*1000); // in milliseconds2 3 String messageSelector = "order = 1";4 Message message = jt.receiveSelected(DESTINATION_NAME, messageSelector);5 6 if (message != null && message instanceof TextMessage) {7 String text = ((TextMessage) message).getText();8 System.out.println(text);9 }
消息选择器的语法类似于sql。你可能注意到在接收的时候,有调用jt.setReceiveTimeout(3*1000);这是因为JmsTemplate所有的接收,包括前面讲的和后面要讲的,都是阻塞式的——阻塞线程,等待接收,直到超过了预先设定的receiveTimeout,单位是毫秒。而它的初始值是0,表示无限等待。
4.选择接收并转换的方法
将选择器和转换进行叠加,我们得到了另外的三个方法:
- public Object receiveSelectedAndConvert(String messageSelector)
- public Object receiveSelectedAndConvert(Destination destination, String messageSelector)
- public Object receiveSelectedAndConvert(String destinationName, String messageSelector)
如果你理解了选择器和转换的接收,应该可以轻松了解上面的方法。这里给出一个demo:
jt.setReceiveTimeout(3 * 1000); // in milliseconds String messageSelector = "order = 1";Object data = jt.receiveSelectedAndConvert(DESTINATION_NAME, messageSelector); if (data != null && data instanceof String) { System.out.println(data);}
阅读全文
0 0
- ActiveMQ——4.Spring-JmsTemplate之发送与接收
- ActiveMQ——5.Spring-JmsTemplate之浏览与执行
- 淘淘商城系列——Spring与ActiveMQ的整合及用JmsTemplate发送消息
- Spring与ActiveMQ整合及用JmsTemplate发送消息
- 轻量级Spring 之 JmsTemplate 接收消息和发送消息
- ActiveMQ——6.Spring-JmsTemplate特性设置
- 学习淘淘商城第六十课(Spring与Activemq的整合及用JmsTemplate发送消息)
- ActiveMQ使用spring JmsTemplate发送消息(一)
- ActiveMQ使用spring JmsTemplate发送消息(一)
- 【MQ】ActiveMQ(三)——spring管理ActiveMQ,实现发送和接收效果
- activeMQ之点对点(p2p)发送与接收消息
- spring的jms:用spring的JmsTemplate发送和接收消息
- spring的jms:用spring的JmsTemplate发送和接收消息 .
- spring的jms:用spring的JmsTemplate发送和接收消息
- activemq的连接池,通过spring的JmsTemplate发送消息到指定的Destination
- activemq的连接池,通过spring的JmsTemplate发送消息到指定的Destination
- ActiveMQ 整合 Spring 发送和接收消息
- activeMQ,spring的jmstemplate简单例子
- mysql存储最大字段数,长度含义
- Insert or Merge(25 分)
- Linux指令用之记之-find
- 04、Android开发基础之相对布局
- win7 _Windows文件共享设置要点
- ActiveMQ——4.Spring-JmsTemplate之发送与接收
- 阿里云新手必看文章-如何领取阿里云优惠券
- storm 1.1.1 起步总结,摸索中走过的坑,如何避免输出无关信息
- [BZOJ]3676 [APIO2014] 回文串 回文自动机
- 听说写蚊帐,就可以 转到 B
- ASP.NET 服务器部署IIS程序池进程标示配置要和SQL SERVER一致,否则不能拽出数据
- android 百度地图 marker设置忽明忽暗闪烁点
- EasyPlayer windows RTSP播放器OCX插件使用说明
- 为什么我们要用数据可视化?数据可视化的4个优势