发送消息

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

在上面的示例中,通过传递对ConnectionFactory的引用来构造JmsTemplate。作为替代方案,还提供了一个零参数构造函数和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;
		}
	});
}

这将产生以下形式的消息:

MapMessage={
	Header={
		...标准头部...
		CorrelationID={123-00001}
	}
	Properties={
		AccountID={Integer:1234}
	}
	Fields={
		Name={String:Mark}
		Age={Integer:47}
	}
}

使用SessionCallbackProducerCallback

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