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.