跳到主要内容

发送消息

ChatGPT-4o 中英对照 Sending a Message

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");
}
});
}
}
java

在前面的示例中,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)支持在 StringTextMessagebyte[]BytesMessage、以及 java.util.MapMapMessage 之间进行转换。通过使用转换器,您和您的应用程序代码可以专注于通过 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;
}
});
}
java

这将导致如下形式的消息:

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

使用 SessionCallbackProducerCallback

虽然发送操作涵盖了许多常见的使用场景,但有时您可能希望对 JMS SessionMessageProducer 执行多个操作。SessionCallbackProducerCallback 分别公开了 JMS SessionSession / MessageProducer 对。JmsTemplate 上的 execute() 方法运行这些回调方法。