JMS
jakarta.jms.ConnectionFactory
介面提供建立 jakarta.jms.Connection
以與 JMS 訊息代理互動的標準方法。雖然 Spring 需要 ConnectionFactory
才能與 JMS 協同運作,但您通常不需要直接使用它,而是可以依賴更高層級的訊息抽象化。(詳情請參閱 Spring Framework 參考文件中的相關章節。)Spring Boot 也會自動組態必要的基礎架構以發送和接收訊息。
ActiveMQ "Classic" 支援
當 ActiveMQ "Classic" 在類別路徑上可用時,Spring Boot 可以組態 ConnectionFactory
。
如果您使用 spring-boot-starter-activemq ,則會提供連線到 ActiveMQ "Classic" 實例的必要依賴,以及與 JMS 整合的 Spring 基礎架構。 |
ActiveMQ "Classic" 組態由 spring.activemq.*
中的外部組態屬性控制。預設情況下,ActiveMQ "Classic" 自動組態為使用 TCP 傳輸,預設連線到 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
使用合理的設定包裝原生 ConnectionFactory
,您可以使用 spring.jms.*
中的外部組態屬性來控制這些設定
-
屬性
-
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 以取得更多支援的選項。您也可以註冊任意數量的 bean 來實作 ActiveMQConnectionFactoryCustomizer 以進行更進階的自訂。 |
預設情況下,ActiveMQ "Classic" 會在目的地尚不存在時建立目的地,以便根據其提供的名稱解析目的地。
ActiveMQ Artemis 支援
當 Spring Boot 偵測到 ActiveMQ Artemis 在類別路徑上可用時,它可以自動組態 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
使用合理的設定包裝原生 ConnectionFactory
,您可以使用 spring.jms.*
中的外部組態屬性來控制這些設定
-
屬性
-
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
以取得更多支援的選項。
不涉及 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 可以以類似的方式注入。如果定義了 DestinationResolver 或 MessageConverter bean,它會自動與自動組態的 JmsTemplate 相關聯。 |
接收訊息
當 JMS 基礎架構存在時,任何 bean 都可以使用 @JmsListener
註解來建立監聽器端點。如果未定義 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 API 文件以取得更多詳細資訊。 |
如果您需要建立更多 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?) {
// ...
}
}