发送消息
JmsTemplate 包含许多方便的方法来发送消息。发送方法通过使用 jakarta.jms.Destination 对象指定目标,其他方法通过在 JNDI 查找中使用 String 指定目标。没有目标参数的 send 方法使用默认目标。
下面的示例使用 MessageCreator 回调从提供的 Session 对象创建一条文本消息:
import jakarta.jms.ConnectionFactory;
import jakarta.jms.JMSException;
import jakarta.jms.Message;
import jakarta.jms.Queue;
import jakarta.jms.Session;
import org.springframework.jms.core.MessageCreator;
import org.springframework.jms.core.JmsTemplate;
public class JmsQueueSender {
private JmsTemplate jmsTemplate;
private Queue queue;
public void setConnectionFactory(ConnectionFactory cf) {
this.jmsTemplate = new JmsTemplate(cf);
}
public void setQueue(Queue queue) {
this.queue = queue;
}
public void simpleSend() {
this.jmsTemplate.send(this.queue, new MessageCreator() {
public Message createMessage(Session session) throws JMSException {
return session.createTextMessage("hello queue world");
}
});
}
}
在前面的示例中,JmsTemplate 是通过传递一个对 ConnectionFactory 的引用来构造的。作为替代方案,提供了一个无参数构造函数和 connectionFactory,可以用于以 JavaBean 风格构造实例(使用 BeanFactory 或普通 Java 代码)。或者,可以考虑从 Spring 的 JmsGatewaySupport 便利基类派生,该类为 JMS 配置提供了预构建的 bean 属性。
send(String destinationName, MessageCreator creator) 方法允许你使用目标的字符串名称发送消息。如果这些名称在 JNDI 中注册,你应该将模板的 destinationResolver 属性设置为 JndiDestinationResolver 的实例。
如果你创建了 JmsTemplate 并指定了一个默认目的地,send(MessageCreator c) 会将消息发送到该目的地。
使用消息转换器
为了方便发送领域模型对象,JmsTemplate 提供了多种发送方法,这些方法将 Java 对象作为消息数据内容的参数。JmsTemplate 中的重载方法 convertAndSend() 和 receiveAndConvert() 将转换过程委托给 MessageConverter 接口的一个实例。这个接口定义了一个简单的契约,用于在 Java 对象和 JMS 消息之间进行转换。默认实现(SimpleMessageConverter)支持在 String 和 TextMessage、byte[] 和 BytesMessage、以及 java.util.Map 和 MapMessage 之间进行转换。通过使用转换器,您和您的应用程序代码可以专注于通过 JMS 发送或接收的业务对象,而不必关心它如何表示为 JMS 消息的细节。
沙箱目前包括一个 MapMessageConverter,它使用反射在 JavaBean 和 MapMessage 之间进行转换。您可能自己实现的其他流行实现选择是使用现有的 XML 编组包(例如 JAXB 或 XStream)来创建表示对象的 TextMessage 的转换器。
为了适应无法在转换器类中通用封装的消息属性、头和主体的设置,MessagePostProcessor 接口允许您在消息被转换后但在发送之前访问该消息。以下示例展示了如何在 java.util.Map 被转换为消息后修改消息头和属性:
public void sendWithConversion() {
Map map = new HashMap();
map.put("Name", "Mark");
map.put("Age", new Integer(47));
jmsTemplate.convertAndSend("testQueue", map, 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:47}
}
}
使用 SessionCallback 和 ProducerCallback
虽然发送操作涵盖了许多常见的使用场景,但有时您可能希望对 JMS Session 或 MessageProducer 执行多个操作。SessionCallback 和 ProducerCallback 分别公开了 JMS Session 和 Session / MessageProducer 对。JmsTemplate 上的 execute() 方法运行这些回调方法。