JMS
jakarta.jms.ConnectionFactory
インターフェースは、JMS ブローカーと対話するための jakarta.jms.Connection
を作成する標準的な方法を提供します。Spring は JMS を使用するために ConnectionFactory
を必要としますが、通常は直接使用する必要はなく、代わりに高レベルのメッセージング抽象化に依存できます。(詳細については、Spring Framework リファレンスドキュメントの関連セクションを参照してください)Spring Boot は、メッセージを送受信するために必要なインフラストラクチャーを自動構成します。
ActiveMQ「クラシック」サポート
ActiveMQ「クラシック」 [Apache] (英語) がクラスパスで使用可能な場合、Spring Boot は ConnectionFactory
を構成できます。
spring-boot-starter-activemq を使用する場合、JMS と統合するための Spring インフラストラクチャと同様に、ActiveMQ の「クラシック」インスタンスに接続するために必要な依存関係が提供されます。 |
ActiveMQ の「クラシック」構成は、spring.activemq.*
の外部構成プロパティによって制御されます。デフォルトでは、ActiveMQ "Classic" は TCP トランスポート [Apache] (英語) を使用するように自動構成され、デフォルトで tcp://localhost:61616
に接続します。次の例は、デフォルトのブローカー URL を変更する方法を示しています。
プロパティ
YAML
spring.activemq.broker-url=tcp://192.168.1.210:9876
spring.activemq.user=admin
spring.activemq.password=secret
spring:
activemq:
broker-url: "tcp://192.168.1.210:9876"
user: "admin"
password: "secret"
デフォルトでは、CachingConnectionFactory
は、spring.jms.*
の外部構成プロパティによって制御できる適切な設定でネイティブ ConnectionFactory
をラップします。
プロパティ
YAML
spring.jms.cache.session-cache-size=5
spring:
jms:
cache:
session-cache-size: 5
ネイティブプーリングを使用する場合は、次の例に示すように、org.messaginghub:pooled-jms
に依存関係を追加し、それに応じて JmsPoolConnectionFactory
を構成することにより、使用できます。
プロパティ
YAML
spring.activemq.pool.enabled=true
spring.activemq.pool.max-connections=50
spring:
activemq:
pool:
enabled: true
max-connections: 50
サポートされるオプションの詳細については、ActiveMQProperties (Javadoc) を参照してください。より高度なカスタマイズのために、ActiveMQConnectionFactoryCustomizer を実装する任意の数の Bean を登録することもできます。 |
デフォルトでは、ActiveMQ "Classic" は宛先がまだ存在しない場合にそれを作成し、指定された名前に対して宛先が解決されるようにします。
ActiveMQArtemis サポート
Spring Boot は、クラスパスで ActiveMQ Artemis [Apache] (英語) が使用可能であることを検出すると、ConnectionFactory
を自動構成できます。ブローカーが存在する場合、埋め込みモードのブローカーは自動的に起動および構成されます(モードプロパティが明示的に設定されていない場合)。サポートされるモードは、embedded
(組み込みブローカーが必要であり、ブローカーがクラスパスで使用できない場合にエラーが発生することを明示するため)および native
(netty
トランスポートプロトコルを使用してブローカーに接続するため)です。後者が構成されている場合、Spring Boot は、デフォルト設定でローカルマシンで実行されているブローカーに接続する ConnectionFactory
を構成します。
spring-boot-starter-artemis を使用する場合は、既存の ActiveMQ Artemis インスタンスに接続するために必要な依存関係と、JMS と統合するための Spring インフラストラクチャが提供されます。アプリケーションに org.apache.activemq:artemis-jakarta-server を追加すると、組み込みモードを使用できます。 |
ActiveMQ Artemis 構成は、spring.artemis.*
の外部構成プロパティによって制御されます。例: application.properties
で次のセクションを宣言できます:
プロパティ
YAML
spring.artemis.mode=native
spring.artemis.broker-url=tcp://192.168.1.210:9876
spring.artemis.user=admin
spring.artemis.password=secret
spring:
artemis:
mode: native
broker-url: "tcp://192.168.1.210:9876"
user: "admin"
password: "secret"
ブローカーを埋め込むときに、永続性を有効にし、使用可能にする必要がある宛先をリストするかどうかを選択できます。これらをコンマ区切りリストとして指定して、デフォルトのオプションで作成するか、型 org.apache.activemq.artemis.jms.server.config.JMSQueueConfiguration
または org.apache.activemq.artemis.jms.server.config.TopicConfiguration
の Bean をそれぞれ高度なキューおよびトピック構成に定義できます。
デフォルトでは、CachingConnectionFactory
は、spring.jms.*
の外部構成プロパティによって制御できる適切な設定でネイティブ ConnectionFactory
をラップします。
プロパティ
YAML
spring.jms.cache.session-cache-size=5
spring:
jms:
cache:
session-cache-size: 5
ネイティブプーリングを使用したい場合は、次の例に示すように、org.messaginghub:pooled-jms
に依存関係を追加し、それに応じて JmsPoolConnectionFactory
を構成することで実行できます。
プロパティ
YAML
spring.artemis.pool.enabled=true
spring.artemis.pool.max-connections=50
spring:
artemis:
pool:
enabled: true
max-connections: 50
サポートされるオプションの詳細については、ArtemisProperties
(Javadoc) を参照してください。
JNDI ルックアップは含まれず、宛先は、ActiveMQ Artemis 構成の name
属性、または構成を通じて提供された名前のいずれかを使用して、その名前に対して解決されます。
JNDI ConnectionFactory を使用する
アプリケーションサーバーでアプリケーションを実行している場合、Spring Boot は JNDI を使用して JMS ConnectionFactory
を見つけようとします。デフォルトでは、java:/JmsXA
と java:/XAConnectionFactory
の場所がチェックされます。次の例に示すように、別の場所を指定する必要がある場合は、spring.jms.jndi-name
プロパティを使用できます。
プロパティ
YAML
spring.jms.jndi-name=java:/MyConnectionFactory
spring:
jms:
jndi-name: "java:/MyConnectionFactory"
メッセージの送信
Spring の JmsTemplate
は自動構成されており、次の例に示すように、独自の Bean に直接オートワイヤーできます。
Java
Kotlin
import org.springframework.jms.core.JmsTemplate;
import org.springframework.stereotype.Component;
@Component
public class MyBean {
private final JmsTemplate jmsTemplate;
public MyBean(JmsTemplate jmsTemplate) {
this.jmsTemplate = jmsTemplate;
}
// ...
public void someMethod() {
this.jmsTemplate.convertAndSend("hello");
}
}
import org.springframework.jms.core.JmsTemplate
import org.springframework.stereotype.Component
@Component
class MyBean(private val jmsTemplate: JmsTemplate) {
// ...
fun someMethod() {
jmsTemplate.convertAndSend("hello")
}
}
JmsMessagingTemplate (Javadoc) は、同様の方法で注入できます。DestinationResolver または MessageConverter Bean が定義されている場合、自動構成された JmsTemplate に自動的に関連付けられます。 |
メッセージの受信
JMS インフラストラクチャが存在する場合、任意の Bean に @JmsListener
のアノテーションを付けて、リスナーエンドポイントを作成できます。JmsListenerContainerFactory
が定義されていない場合、デフォルトの JmsListenerContainerFactory
が自動的に構成されます。DestinationResolver
、MessageConverter
、jakarta.jms.ExceptionListener
Bean が定義されている場合、デフォルトのファクトリに自動的に関連付けられます。
デフォルトでは、デフォルトのファクトリはトランザクションです。JtaTransactionManager
が存在するインフラストラクチャで実行すると、デフォルトでリスナーコンテナーに関連付けられます。そうでない場合、sessionTransacted
フラグが有効になります。後者のシナリオでは、リスナーメソッド(またはそのデリゲート)に @Transactional
を追加することにより、ローカルデータストアトランザクションを受信メッセージの処理に関連付けることができます。これにより、ローカルトランザクションが完了すると、受信メッセージが確認されます。これには、同じ JMS セッションで実行されたレスポンスメッセージの送信も含まれます。
次のコンポーネントは、someQueue
宛先にリスナーエンドポイントを作成します。
Java
Kotlin
import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;
@Component
public class MyBean {
@JmsListener(destination = "someQueue")
public void processMessage(String content) {
// ...
}
}
import org.springframework.jms.annotation.JmsListener
import org.springframework.stereotype.Component
@Component
class MyBean {
@JmsListener(destination = "someQueue")
fun processMessage(content: String?) {
// ...
}
}
詳細については、@EnableJms の Javadoc を参照してください。 |
さらに JmsListenerContainerFactory
インスタンスを作成する必要がある場合、またはデフォルトをオーバーライドする場合は、Spring Boot が提供する DefaultJmsListenerContainerFactoryConfigurer
を使用して、自動構成されたものと同じ設定で DefaultJmsListenerContainerFactory
を初期化できます。
たとえば、次の例では、特定の MessageConverter
を使用する別のファクトリを公開しています。
Java
Kotlin
import jakarta.jms.ConnectionFactory;
import org.springframework.boot.autoconfigure.jms.DefaultJmsListenerContainerFactoryConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jms.config.DefaultJmsListenerContainerFactory;
@Configuration(proxyBeanMethods = false)
public class MyJmsConfiguration {
@Bean
public DefaultJmsListenerContainerFactory myFactory(DefaultJmsListenerContainerFactoryConfigurer configurer) {
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
ConnectionFactory connectionFactory = getCustomConnectionFactory();
configurer.configure(factory, connectionFactory);
factory.setMessageConverter(new MyMessageConverter());
return factory;
}
private ConnectionFactory getCustomConnectionFactory() {
return ...
}
}
import jakarta.jms.ConnectionFactory
import org.springframework.boot.autoconfigure.jms.DefaultJmsListenerContainerFactoryConfigurer
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.jms.config.DefaultJmsListenerContainerFactory
@Configuration(proxyBeanMethods = false)
class MyJmsConfiguration {
@Bean
fun myFactory(configurer: DefaultJmsListenerContainerFactoryConfigurer): DefaultJmsListenerContainerFactory {
val factory = DefaultJmsListenerContainerFactory()
val connectionFactory = getCustomConnectionFactory()
configurer.configure(factory, connectionFactory)
factory.setMessageConverter(MyMessageConverter())
return factory
}
fun getCustomConnectionFactory() : ConnectionFactory? {
return ...
}
}
次に、次のように、@JmsListener
アノテーション付きメソッドでファクトリを使用できます。
Java
Kotlin
import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;
@Component
public class MyBean {
@JmsListener(destination = "someQueue", containerFactory = "myFactory")
public void processMessage(String content) {
// ...
}
}
import org.springframework.jms.annotation.JmsListener
import org.springframework.stereotype.Component
@Component
class MyBean {
@JmsListener(destination = "someQueue", containerFactory = "myFactory")
fun processMessage(content: String?) {
// ...
}
}