JMS

ConnectionFactory介面提供了一種標準方法來建立與JMS代理互動的Connection。儘管Spring需要一個ConnectionFactory來使用JMS,但您通常不需要直接使用它,而是可以依賴更高級別的訊息抽象。(有關詳細資訊,請參閱Spring Framework參考文件的相關部分。)Spring Boot還會自動配置傳送和接收訊息所需的基礎設施。

ActiveMQ "Classic"支援

當類路徑中存在ActiveMQ "Classic"時,Spring Boot可以配置一個ConnectionFactory。如果代理存在,則會自動啟動並配置一個嵌入式代理(前提是透過配置未指定代理URL,並且配置中未停用嵌入式代理)。

如果您使用spring-boot-starter-activemq,則提供了連線到ActiveMQ "Classic"例項所需的依賴項,以及與JMS整合的Spring基礎設施。將org.apache.activemq:activemq-broker新增到您的應用程式中,您就可以使用嵌入式代理。

ActiveMQ "Classic"配置由spring.activemq.*中的外部配置屬性控制。

如果activemq-broker在類路徑中,ActiveMQ "Classic"會被自動配置為使用VM傳輸,這會在相同的JVM例項中啟動一個嵌入式代理。

您可以透過配置spring.activemq.embedded.enabled屬性來停用嵌入式代理,如以下示例所示:

  • 屬性

  • YAML

spring.activemq.embedded.enabled=false
spring:
  activemq:
    embedded:
      enabled: false

如果您配置代理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"

如果您想完全控制嵌入式代理,請參閱ActiveMQ "Classic"文件以獲取更多資訊。

預設情況下,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。您還可以註冊任意數量實現ActiveMQConnectionFactoryCustomizer的bean以進行更高階的定製。

預設情況下,ActiveMQ "Classic"會在目的地不存在時建立它,因此目的地會根據其提供的名稱進行解析。

ActiveMQ Artemis支援

當Spring Boot檢測到類路徑中存在ActiveMQ Artemis時,它會自動配置一個ConnectionFactory。如果代理存在,則會自動啟動並配置一個嵌入式代理(除非已顯式設定mode屬性)。支援的模式有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"

嵌入代理時,您可以選擇是否啟用永續性並列出應可用的目的地。這些可以指定為逗號分隔列表以使用預設選項建立它們,或者您可以定義JMSQueueConfigurationTopicConfiguration型別的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:/JmsXAjava:/XAConnectionFactory位置。如果需要指定替代位置,可以使用spring.jms.jndi-name屬性,如以下示例所示

  • 屬性

  • YAML

spring.jms.jndi-name=java:/MyConnectionFactory
spring:
  jms:
    jndi-name: "java:/MyConnectionFactory"

傳送訊息

Spring的JmsClient已自動配置,您可以將其直接自動裝配到您自己的bean中,如以下示例所示

  • Java

  • Kotlin

import org.springframework.jms.core.JmsClient;
import org.springframework.stereotype.Component;

@Component
public class MyBean {

	private final JmsClient jmsClient;

	public MyBean(JmsClient jmsClient) {
		this.jmsClient = jmsClient;
	}

	// ...

	public void someMethod() {
		this.jmsClient.destination("myQueue").send("hello");
	}

}
import org.springframework.jms.core.JmsClient
import org.springframework.stereotype.Component

@Component
class MyBean(private val jmsClient: JmsClient) {

	// ...

	fun someMethod() {
		jmsClient.destination("myQueue").send("hello")
	}

}
JmsMessagingTemplate可以透過類似的方式注入,兩者都使用傳統的JmsTemplate,後者也可以注入。如果定義了DestinationResolverMessageConverter bean,它們會自動與自動配置的JmsTemplate關聯。

接收訊息

當JMS基礎設施存在時,任何bean都可以用@JmsListener註解來建立一個監聽器端點。如果沒有定義JmsListenerContainerFactory,則會自動配置一個預設的。如果定義了DestinationResolverMessageConverterExceptionListener bean,它們會自動與預設工廠關聯。

在大多數情況下,訊息監聽器容器應該針對原生ConnectionFactory進行配置。這樣每個監聽器容器都有自己的連線,這使得它在本地恢復方面擁有完全的責任。自動配置使用ConnectionFactoryUnwrapper從自動配置的連線工廠中解包原生連線工廠。

自動配置僅解包CachedConnectionFactory

預設情況下,預設工廠是事務性的。如果您在存在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.jms.ConnectionFactoryUnwrapper;
import org.springframework.boot.jms.autoconfigure.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,
			ConnectionFactory connectionFactory) {
		DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
		configurer.configure(factory, ConnectionFactoryUnwrapper.unwrapCaching(connectionFactory));
		factory.setMessageConverter(new MyMessageConverter());
		return factory;
	}

}
import jakarta.jms.ConnectionFactory
import org.springframework.boot.jms.ConnectionFactoryUnwrapper
import org.springframework.boot.jms.autoconfigure.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,
				  connectionFactory: ConnectionFactory): DefaultJmsListenerContainerFactory {
		val factory = DefaultJmsListenerContainerFactory()
		configurer.configure(factory, ConnectionFactoryUnwrapper.unwrapCaching(connectionFactory))
		factory.setMessageConverter(MyMessageConverter())
		return factory
	}

}
在上面的示例中,定製使用ConnectionFactoryUnwrapper將原生連線工廠與訊息監聽器容器關聯,與自動配置的工廠方式相同。

然後,您可以在任何帶有@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?) {
		// ...
	}

}
© . This site is unofficial and not affiliated with VMware.