傳送訊息

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) 支援 StringTextMessagebyte[]BytesMessage 以及 java.util.MapMapMessage 之間的轉換。透過使用轉換器,你和你的應用程式碼可以專注於透過 JMS 傳送或接收的業務物件,而無需關心它如何表示為 JMS 訊息的細節。

當前 sandbox 中包含一個 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}
	}
}

使用 SessionCallbackProducerCallback

雖然傳送操作涵蓋了許多常見的使用場景,但有時你可能希望對 JMS SessionMessageProducer 執行多個操作。SessionCallbackProducerCallback 分別暴露了 JMS Session 以及 Session / MessageProducer 對。JmsTemplate 上的 execute() 方法會執行這些回撥方法。