1. 概要

Springは、JMSAPIの使用を簡素化するJMS統合フレームワークを提供します。 この記事では、このような統合の基本的な概念を紹介します。

2. Mavenの依存関係

アプリケーションでSpringJMSを使用するには、pom.xmlに必要なアーティファクトを追加する必要があります。

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

アーティファクトの最新バージョンは、ここにあります。

3. JmsTemplate

JmsTemplate クラスは、メッセージを送信または同期的に受信するときに、リソースの作成と解放を処理します。

したがって、この JmsTemplate を使用するクラスは、メソッド定義で指定されているコールバックインターフェイスを実装するだけで済みます。

Spring 4.1以降、 JmsMessagingTemplate 上に構築されています JmsTemplate これは、メッセージングの抽象化との統合を提供します。 org.springframework.messaging.Message。 これにより、一般的な方法で送信するメッセージを作成できます。

4. 接続管理

接続してメッセージを送受信できるようにするには、ConnectionFactoryを構成する必要があります。

ConnectionFactoryは、管理者によって事前構成されたJMS管理対象オブジェクトの1つです。 構成の助けを借りたクライアントは、JMSプロバイダーとの接続を確立します。

Springは2種類のConnectionFactoryを提供します。

  • SingleConnectionFactory –ConnectionFactory インターフェイスの実装であり、すべての createConnection ()呼び出しで同じ接続を返し、closeへの呼び出しを無視します。 ()
  • CachingConnectionFactory – は、 SingleConnectionFactory の機能を拡張し、 Sessions MessageProducers 、および MessageConsumers[ X211X]

5. 宛先管理

上で説明したように、 ConnectionFactory とともに、宛先もJMS管理対象オブジェクトであり、JNDIから保管および取得できます。

Springは、DynamicDestinationResolverなどの汎用リゾルバーとJndiDestinationResolverなどの特定のリゾルバーを提供します。

JmsTemplate は、選択に基づいて、宛先名の解決を実装の1つに委任します。

また、 defaultDestination というプロパティも提供します。これは、特定の宛先を参照しないsendおよびreceive操作で使用されます。

6. メッセージ変換

メッセージコンバータのサポートがないと、SpringJMSは不完全になります。

JmsTemplateConvertAndSend()操作と ReceiveAndConvert()操作の両方に使用するデフォルトの変換戦略は、SimpleMessageConverterクラスです。

SimpleMessageConverter は、 TextMessages BytesMessages MapMessages 、およびObjectMessagesを処理できます。 このクラスは、MessageConverterインターフェースを実装します。

SimpleMessageConverter とは別に、Spring JMSは、 MappingJackson2MessageConverter MarshallingMessageConverter MessagingMessageConverterなどの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. SpringJMSのサンプル

このセクションでは、JmsTemplateを使用してメッセージを送受信する方法を説明します。

メッセージを送信するためのデフォルトのメソッドはJmsTemplate.send()です。 これには2つの主要なパラメーターがあり、最初のパラメーターはJMS宛先であり、2番目のパラメーターはの実装です。 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) { ... }

1つのメソッドに複数のリスナーを追加するには、複数の@JmsListenerアノテーションを追加する必要があります。

@JmsListener アノテーション付きメソッドをサポートするには、構成クラスの1つに@EnableJmsアノテーションを追加する必要があります。

@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()メソッドをオーバーライドしたことに注意してください。このメソッドは、単にエラーメッセージをログに記録します。

次に、 setErrorHandler()メソッドを使用して、DefaultJmsListenerConnectionFactoryでエラーハンドラサービスを参照する必要があります。

@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. 結論

このチュートリアルでは、SpringJMSの構成と基本概念について説明しました。 また、メッセージの送受信に使用されるSpring固有のJmsTemplateクラスについても簡単に説明しました。

コードの実装はGitHubプロジェクトにあります。