此版本仍在开发中,尚不被认为是稳定的。对于最新的稳定版本,请使用 Spring Framework 6.2.10spring-doc.cadn.net.cn

发送消息

JmsTemplate包含许多发送消息的便捷方法。发送 方法使用jakarta.jms.Destination对象和其他 使用String在 JNDI 查找中。这send方法 不取 destination 参数使用默认 destination。spring-doc.cadn.net.cn

以下示例使用MessageCreator回调以从 提供Session对象:spring-doc.cadn.net.cn

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 属性。spring-doc.cadn.net.cn

send(String destinationName, MessageCreator creator)方法允许您发送一个 消息,使用目标的字符串名称。如果这些名称已在 JNDI 中注册, 您应该将destinationResolver模板的属性转换为JndiDestinationResolver.spring-doc.cadn.net.cn

如果您创建了JmsTemplate并指定了默认目的地,则send(MessageCreator c)向该目标发送消息。spring-doc.cadn.net.cn

使用 JMS 消息转换器

为了方便发送域模型对象,JmsTemplate有 将 Java 对象作为消息数据参数的各种 send 方法 内容。重载的方法convertAndSend()receiveAndConvert()方法JmsTemplate将转换过程委托给MessageConverter接口。该接口定义了一个简单的合约,用于在 Java 对象和 JMS 消息。默认实现 (SimpleMessageConverter)支持转换 之间StringTextMessage,byte[]BytesMessagejava.util.MapMapMessage.通过使用转换器,您和您的应用程序代码可以专注于 通过 JMS 发送或接收的业务对象,并且与 如何将其表示为 JMS 消息的详细信息。spring-doc.cadn.net.cn

沙盒当前包括一个MapMessageConverter,它使用反射来转换 在 JavaBean 和MapMessage.您可能使用的其他常用实现选项 实现自己是使用现有 XML 封送包(例如 JAXB 或 XStream)创建TextMessage表示对象。spring-doc.cadn.net.cn

适应邮件的属性、标头和正文的设置,而这些设置不能 通用封装在转换器类中,则MessagePostProcessor接口 允许您在邮件转换后但在发送之前访问邮件。这 以下示例演示如何修改消息标头和属性java.util.Map转换为消息:spring-doc.cadn.net.cn

import java.util.HashMap;
import java.util.Map;

import jakarta.jms.JMSException;
import jakarta.jms.Message;

import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessagePostProcessor;

public class JmsSenderWithConversion {

	private JmsTemplate jmsTemplate;

	public void sendWithConversion() {
		Map<String, Object> map = new HashMap<>();
		map.put("Name", "Mark");
		map.put("Age", 47);
		jmsTemplate.convertAndSend("testQueue", map, new MessagePostProcessor() {
			public Message postProcessMessage(Message message) throws JMSException {
				message.setIntProperty("AccountID", 1234);
				message.setJMSCorrelationID("123-00001");
				return message;
			}
		});
	}

}

这将产生以下形式的消息:spring-doc.cadn.net.cn

MapMessage={
	Header={
		... standard headers ...
		CorrelationID={123-00001}
	}
	Properties={
		AccountID={Integer:1234}
	}
	Fields={
		Name={String:Mark}
		Age={Integer:47}
	}
}
这个特定于 JMS 的org.springframework.jms.support.converter.MessageConverter安排对 JMS 消息类型进行作,并负责立即转换 自jakarta.jms.TextMessage,jakarta.jms.BytesMessage等。对于支持 通用消息有效负载,使用org.springframework.messaging.converter.MessageConverterJmsMessagingTemplate或优选JmsClient作为您的中央代表。

SessionCallbackProducerCallbackJmsTemplate

虽然发送作涵盖了许多常见的使用方案,但有时您可能 想要在 JMS 上执行多个作SessionMessageProducer.这SessionCallbackProducerCallback公开 JMSSessionSession / MessageProducer对,分别。这execute()方法JmsTemplate跑 这些回调方法。spring-doc.cadn.net.cn

发送消息JmsClient

import jakarta.jms.ConnectionFactory;

import org.springframework.jms.core.JmsClient;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;

public class JmsClientSample {

	private final JmsClient jmsClient;

	public JmsClientSample(ConnectionFactory connectionFactory) {
		// For custom options, use JmsClient.builder(ConnectionFactory)
		this.jmsClient = JmsClient.create(connectionFactory);
	}

	public void sendWithConversion() {
		this.jmsClient.destination("myQueue")
				.withTimeToLive(1000)
				.send("myPayload");  // optionally with a headers Map next to the payload
	}

	public void sendCustomMessage() {
		Message<?> message = MessageBuilder.withPayload("myPayload").build();  // optionally with headers
		this.jmsClient.destination("myQueue")
				.withTimeToLive(1000)
				.send(message);
	}
}

后处理传出邮件

应用程序通常需要在发送消息之前拦截消息,例如,将消息属性添加到所有传出消息。 这org.springframework.messaging.core.MessagePostProcessor基于 spring-messagingMessage可以做到这一点, 在JmsClient.它将用于使用sendsendAndReceive方法。spring-doc.cadn.net.cn

下面是拦截器向所有传出消息添加“tenantId”属性的示例。spring-doc.cadn.net.cn

import jakarta.jms.ConnectionFactory;

import org.springframework.jms.core.JmsClient;
import org.springframework.messaging.Message;
import org.springframework.messaging.core.MessagePostProcessor;
import org.springframework.messaging.support.MessageBuilder;

public class JmsClientWithPostProcessor {

	private final JmsClient jmsClient;

	public JmsClientWithPostProcessor(ConnectionFactory connectionFactory) {
		this.jmsClient = JmsClient.builder(connectionFactory)
				.messagePostProcessor(new TenantIdMessageInterceptor("42"))
				.build();
	}

	public void sendWithPostProcessor() {
		this.jmsClient.destination("myQueue")
				.withTimeToLive(1000)
				.send("myPayload");
	}

	static class TenantIdMessageInterceptor implements MessagePostProcessor {

		private final String tenantId;

		public TenantIdMessageInterceptor(String tenantId) {
			this.tenantId = tenantId;
		}

		@Override
		public Message<?> postProcessMessage(Message<?> message) {
			return MessageBuilder.fromMessage(message)
					.setHeader("tenantId", this.tenantId)
					.build();
		}
	}
}