技术开发 频道

JMS支持

要开始使用JmsTemplate前,你需要选择JMS 1.0.2的实现,JmsTemplate102,还是JMS 1.1的实现,JmsTemplate。检查一下你的JMS供应者支持那个版本。

发送消息
JmsTemplate包含许多有用的方法来发送消息。这些发送方法可以使用javax.jms.Destination对象指定destination,也可以使用字符串在JNDI中查找destination。没有destination参数的发送方法使用默认的destination。这里有个例子使用1.0.2的实现发送消息到一个队列。

import javax.jms.ConnectionFactory; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.Queue; import javax.jms.Session; import org.springframework.jms.core.JmsTemplate; import org.springframework.jms.core.JmsTemplate102; import org.springframework.jms.core.MessageCreator; public class JmsQueueSender { private JmsTemplate jt; private ConnectionFactory connFactory; private Queue queue; public void simpleSend() { jt = new JmsTemplate102(connFactory, false); jt.send(queue, new MessageCreator() { public Message createMessage(Session session) throws JMSException { return session.createTextMessage("hello queue world"); } }); } public void setConnectionFactory(ConnectionFactory cf) { connFactory = cf; } public void setQueue(Queue q) { queue = q; } }

 
这个例子使用MessageCreator回调接口从所提供的会话对象中创建一个文本消息,并且通过一个ConnectionFactory的引用和指定消息域的布尔值来创建JmsTemplate。BeanFactory使用一个没有参数的构造方法和setConnectionFactory/Queue方法来用构造实例。simpleSend方法在下面修改为发送消息到一个主题而不是队列。

public void simpleSend() { jt = new JmsTemplate102(connFactory, true); jt.send(topic, new MessageCreator() { public Message createMessage(Session session) throws JMSException { return session.createTextMessage("hello topic world"); } }); }


当在应用上下文中配置JMS 1.0.2时,重要的是记得设定布尔属性 PubSubDomain的值以确定你是要发送到队列还是主题。

方法send(String destinationName, MessageCreator c)让你利用destination的名字发送消息。如果这个名字在JNDI中注册,你应当将模板中的DesinationResolver属性设置为JndiDestinationResolver的一个实例。

如果你创建JmsTemplate并指定一个默认的destination,send(MessageCreator c)发送消息到这个destination。

同步接收
虽然JMS一般都是应用在异步操作,但它也可能同步接收消息。重载的receive方法就提供这个功能。在同步接收时,调用线程被阻塞直到收到一个消息。这是一个危险的操作,因为调用线程可能会被无限期的阻塞。receiveTimeout属性指定接收者在放弃等待一个消息前要等多久。

使用消息转换器
为了更容易的发送域模式对象,JmsTemplate有多种将一个Java对象作为消息数据内容的发送方法。在JmsTemplate中重载方法convertAndSend和receiveAndConvert,可以将转换过程委派到MessageConverter接口的一个实例。这个接口定义了一个简单的Java对象和JMS消息之间进行转换的约定。它的默认实现SimpleMessageConverter支持在String和TextMessage,byte[]和BytesMesssage,java.util.Map和MapMessage之间进行转换。通过使用转换器,你的应用代码可以专注于通过JMS发送或接收的业务对象,并不用为了怎样将它描述为一个JMS消息而费心。

沙箱目前包含MapMessageConverter,它使用反射在JavaBean和MapMessage之间进行转换。你还可以选择使用XML组包的转换器,如JAXB、Castor、XMLBeans或Xstream,来创建一个TextMessage来描述该对象。

消息属性、消息头和消息体的设置,一般不能被封装在一个转换器类中,为了调整它们,接口MessagePostProcessor可以使你在消息转换后,发送前,访问消息。下面的例子展示了如何在一个java.util.Map被转换为消息之后修改一个消息的头和属性。

public void sendWithConversion() { Map m = new HashMap(); m.put("Name", "Mark"); m.put("Age", new Integer(35)); jt.convertAndSend("testQueue", m, new MessagePostProcessor() { public Message postProcessMessage(Message message) throws JMSException { message.setIntProperty("AccountID", 1234); message.setJMSCorrelationID("123-00001"); return message; } }); }

 
这是一个由上面得到的消息

MapMessage={ Header={ ... standard headers ... CorrelationID={123-00001} } Properties={ AccountID={Integer:1234} } Fields={ Name={String:Mark} Age={Integer:35} } }


SessionCallback和ProducerCallback
虽然发送操作涵盖了很多普通的使用场景,但是有些情况你需要在JMS Session或MessageProducer上执行多个操作。SessionCallback和ProduerCallback分别暴露了JMS Session和Session/MessageProducer对。JmsTemplate的execute()方法会执行这些接口上的回调方法。

原文地址

0
相关文章