知識庫 / Spring RSS 訂閱

使用 Spring JMS 入門指南

Spring
HongKong
4
02:44 PM · Dec 06 ,2025

1. 概述

Spring 提供了一個 JMS 集成框架,簡化了 JMS API 的使用。

在本教程中,我們將介紹這種集成的基本概念。

2. Maven 依賴

為了在我們的應用程序中使用 Spring JMS,我們需要在 pom.xml 中添加必要的 Artifacts:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jms</artifactId>
    <version>4.3.3.RELEASE</version>
</dependency>

最新版本的該 Artifact 可以 在此處找到

3. JmsTemplate

JmsTemplate 類負責在發送或同步接收消息時創建和釋放資源。

因此,使用該JmsTemplate的類只需要實現方法定義中指定的回調接口。

從 Spring 4.1 版本開始,JmsMessagingTemplate建立在JmsTemplate之上,這提供了一個與消息抽象的集成,即 org.springframework.messaging.Message。這使得我們可以以通用方式創建消息。

4. 連接管理

為了連接並能夠發送/接收消息,我們需要配置一個 ConnectionFactory

ConnectionFactory 是 JMS 管理對象之一,由管理員預配置。客户端通過配置與 JMS 提供程序建立連接。

Spring 提供了兩種類型的 ConnectionFactory

  • SingleConnectionFactory –ConnectionFactory 接口的實現,它會在所有 createConnection() 調用中返回相同的連接,並忽略 close() 調用
  • CachingConnectionFactory 擴展了 SingleConnectionFactory 的功能,並增加了對 SessionsMessageProducersMessageConsumers 的緩存

5. 目的地管理

如上所述,與 ConnectionFactory 一起,目的地也是 JMS 管理對象,可以從 JNDI 中存儲和檢索。

Spring 提供了通用的解析器,如 DynamicDestinationResolver,以及具體的解析器,例如 JndiDestinationResolver

JmsTemplate 將根據我們的選擇,將目的地名稱的解析委託給其中一個實現。

它還提供一個名為 defaultDestination 的屬性,該屬性將用於在不引用特定目的地的情況下,使用 sendreceive 操作。

6. 消息轉換

Spring JMS 在沒有消息轉換器支持的情況下將不完整。

JmsTemplate 默認的轉換策略,用於ConvertAndSend()ReceiveAndConvert() 操作,是 SimpleMessageConverter 類。

SimpleMessageConverter 能夠處理 TextMessagesBytesMessagesMapMessagesObjectMessages。該類實現了 MessageConverter 接口。

除了 SimpleMessageConverter 之外,Spring JMS 還提供了MappingJackson2MessageConverterMarshallingMessageConverterMessagingMessageConverter 等其他MessageConverter 類。

此外,我們只需通過實現 MessageConverter 接口的 toMessage()FromMessage() 方法,即可創建自定義的消息轉換功能。

下面是一個自定義 MessageConverter 的示例代碼片段:

public class SampleMessageConverter implements MessageConverter {
    public Object fromMessage(Message message) 
      throws JMSException, MessageConversionException {
        //...
    }

    public Message toMessage(Object object, Session session)
      throws JMSException, MessageConversionException { 
        //...
    }
}

7. 示例 Spring JMS

在本節中,我們將學習如何使用 JmsTemplate 發送和接收消息。

發送消息的默認方法是 JmsTemplate.send()。它有兩個關鍵參數:第一個是 JMS 目的地,第二個是 MessageCreator 的實現。 JmsTemplate 使用 MessageCreator 的回調方法 createMessage() 來構造消息。

JmsTemplate.send() 適用於發送純文本消息,但為了發送自定義消息,JmsTemplate 還有一個名為 convertAndSend() 的方法。

以下是這些方法的實現:

public class SampleJmsMessageSender {

    private JmsTemplate jmsTemplate;
    private Queue queue;

    // setters for jmsTemplate & queue

    public void simpleSend() {
        jmsTemplate.send(queue, s -> s.createTextMessage("hello queue world"));
    }
    public void sendMessage(Employee employee) { 
        System.out.println("Jms Message Sender : " + employee); 
        Map<String, Object> map = new HashMap<>(); 
        map.put("name", employee.getName()); map.put("age", employee.getAge()); 
        jmsTemplate.convertAndSend(map); 
    }
}

下面是消息接收器類,即消息驅動型POJO(MDP)。我們可以看到,該類SampleListener實現了MessageListener接口,併為接口方法onMessage()提供了具體的文本實現。

除了onMessage()方法之外,我們的SampleListener類還調用了receiveAndConvert()方法來接收自定義消息:

public class SampleListener implements MessageListener {

    public JmsTemplate getJmsTemplate() {
        return getJmsTemplate();
    }

    public void onMessage(Message message) {
        if (message instanceof TextMessage) {
            try {
                String msg = ((TextMessage) message).getText();
                System.out.println("Message has been consumed : " + msg);
            } catch (JMSException ex) {
                throw new RuntimeException(ex);
            }
        } else {
            throw new IllegalArgumentException("Message Error");
        }
    }

    public Employee receiveMessage() throws JMSException {
        Map map = (Map) getJmsTemplate().receiveAndConvert();
        return new Employee((String) map.get("name"), (Integer) map.get("age"));
    }
}

我們瞭解瞭如何實現 MessageListener, 並且下面我們可以看到在 Spring 應用上下文中它的配置:

<bean id="messageListener" class="com.baeldung.spring.jms.SampleListener" /> 

<bean id="jmsContainer" 
  class="org.springframework.jms.listener.DefaultMessageListenerContainer"> 
    <property name="connectionFactory" ref="connectionFactory"/> 
    <property name="destinationName" ref="IN_QUEUE"/> 
    <property name="messageListener" ref="messageListener" /> 
</bean>

DefaultMessageListenerContainer 是 Spring 提供的默認消息監聽器容器,以及許多其他專用容器。

8. 使用 Java 註解進行基本配置

@JmsListener 是唯一需要的註解,可以將普通 Bean 的方法轉換為 JMS 監聽器端點。 Spring JMS 提供了更多註解,以簡化 JMS 實現。

下面是一些示例類,它們被註解如下:

@JmsListener(destination = "myDestination")
public void SampleJmsListenerMethod(Message<Order> order) { ... }

為了向單個方法添加多個監聽器,我們只需要添加多個 @JmsListener 註解。

我們需要在其中一個配置類中添加 @EnableJms 註解,以支持帶有 @JmsListener 註解的方法:

@Configuration
@EnableJms
public class AppConfig {

    @Bean
    public DefaultJmsListenerContainerFactory jmsListenerContainerFactory() {
        DefaultJmsListenerContainerFactory factory 
          = new DefaultJmsListenerContainerFactory();
        factory.setConnectionFactory(connectionFactory());
        return factory;
    }
}

9. 錯誤處理程序

我們還可以為我們的消息監聽器容器配置自定義錯誤處理程序。

首先,讓我們實現 org.springframework.util.ErrorHandler 接口:

@Service
public class SampleJmsErrorHandler implements ErrorHandler {

    // ... logger

    @Override
    public void handleError(Throwable t) {
        LOG.warn("In default jms error handler...");
        LOG.error("Error Message : {}", t.getMessage());
    }

}

請注意,我們已覆蓋了handleError()方法,它只是記錄錯誤消息。

接下來,我們需要在DefaultJmsListenerConnectionFactory中使用setErrorHandler()方法引用我們的錯誤處理服務。

@Bean
public DefaultJmsListenerContainerFactorybjmsListenerContainerFactory() {
    DefaultJmsListenerContainerFactory factory 
      = new DefaultJmsListenerContainerFactory();
    factory.setConnectionFactory(connectionFactory());
    factory.setErrorHandler(sampleJmsErrorHandler);
    return factory;
}

有了這個,我們的配置錯誤處理程序將捕獲任何未處理的異常並記錄消息。

可選地,我們還可以通過更新我們的appContext.xml,使用傳統的 XML 配置來配置錯誤處理程序。

<bean id="sampleJmsErrorHandler"
  class="com.baeldung.spring.jms.SampleJmsErrorHandler" />

<bean id="jmsContainer"
  class="org.springframework.jms.listener.DefaultMessageListenerContainer">
    <property name="connectionFactory" ref="connectionFactory" />
    <property name="destinationName" value="IN_QUEUE" />
    <property name="messageListener" ref="messageListener" />
    <property name="errorHandler" ref="sampleJmsErrorHandler" />
</bean>

10. 結論

在本文中,我們討論了 Spring JMS 的配置和基本概念。我們還簡要介紹了 Spring 相關的 <em >JmsTemplate</em> 類,這些類用於發送和接收消息。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.