Spring JMS入門
1. 概要
Springは、JMS APIの使用を簡素化するJMS統合フレームワークを提供します。 この記事では、このような統合の基本概念を紹介します。
2. メーベン依存
アプリケーションでSpringJMSを使用するには、pom.xmlに必要なアーティファクトを追加する必要があります。
org.springframework
spring-jms
4.3.3.RELEASE
アーティファクトの最新バージョンはfound hereにすることができます。
3. JmsTemplate
JmsTemplateクラスは、メッセージを送信または同期的に受信するときに、リソースの作成と解放を処理します。
したがって、このJmsTemplateを使用するクラスは、メソッド定義で指定されているコールバックインターフェイスを実装するだけで済みます。
Spring 4.1以降、JmsMessagingTemplateはJmsTemplateの上に構築され、メッセージングの抽象化、つまりorg.springframework.messaging.Message.との統合を提供します。これにより、送信するメッセージを作成できます。一般的な方法で。
4. 接続管理
接続してメッセージを送受信できるようにするには、ConnectionFactoryを構成する必要があります。
A ConnectionFactory is one of the JMS administered objects which are preconfigured by an administrator。 設定の助けを借りて、クライアントはJMSプロバイダーと接続します。
Springは2種類のConnectionFactoryを提供します:
-
SingleConnectionFactory –はConnectionFactoryインターフェースの実装であり、すべてのcreateConnection()呼び出しで同じ接続を返し、close()への呼び出しを無視します。
-
CachingConnectionFactory –は、SingleConnectionFactoryの機能を拡張し、Sessions、MessageProducers、およびMessageConsumersのキャッシュで機能を強化します。
5. 宛先管理
上で説明したように、ConnectionFactoryとともに、宛先もJMS管理対象オブジェクトであり、JNDIに格納および取得できます。
Springは、DynamicDestinationResolverなどの汎用リゾルバーとJndiDestinationResolverなどの特定のリゾルバーを提供します。
JmsTemplateは、選択に基づいて、宛先名の解決を実装の1つに委任します。
また、defaultDestinationと呼ばれるプロパティも提供します。これは、特定の宛先を参照しないsendおよびreceive操作で使用されます。
6. メッセージ変換
Spring JMSは、メッセージコンバーターのサポートがなければ不完全です。
ConvertAndSend()操作とReceiveAndConvert()操作の両方でJmsTemplateが使用するデフォルトの変換戦略は、SimpleMessageConverterクラスです。
The 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. The 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 map = new HashMap<>();
map.put("name", employee.getName()); map.put("age", employee.getAge());
jmsTemplate.convertAndSend(map);
}
}
以下はメッセージレシーバークラスです。これをメッセージ駆動型POJO(MDP)と呼びます。 We can see that the class SampleListener is implementing the MessageListener interface and provides the text specific implementation for the interface method 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アプリケーションコンテキストでの構成を示します。
DefaultMessageListenerContainerは、Springが他の多くの特殊なコンテナーとともに提供するデフォルトのメッセージリスナーコンテナーです。
8. Javaアノテーションを使用した基本構成
The @JmsListener is the only annotation required to convert a method of a normal bean into a JMS listener endpoint. Spring JMSは、JMSの実装を容易にするためにさらに多くのアノテーションを提供します。
以下に注釈を付けたサンプルクラスの一部を見ることができます。
@JmsListener(destination = "myDestination")
public void SampleJmsListenerMethod(Message 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構成を使用してエラーハンドラーを構成することもできます。
10. 結論
このチュートリアルでは、Spring JMSの構成と基本概念について説明しました。 また、メッセージの送受信に使用されるSpring固有のJmsTemplateクラスについても簡単に説明しました。
コードの実装はGitHub projectにあります。