此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Boot 3.4.0spring-doc.cadn.net.cn

JMS 公司

ConnectionFactoryinterface 提供了一种创建Connection用于与 JMS 代理交互。 尽管 Spring 需要一个ConnectionFactory要使用 JMS,您通常不需要自己直接使用它,而是可以依赖更高级别的消息传递抽象。 (有关详细信息,请参阅 Spring Framework 参考文档的相关部分。 Spring Boot 还自动配置了发送和接收消息所需的基础设施。spring-doc.cadn.net.cn

ActiveMQ “Classic” 支持

ActiveMQ “Classic” 在 Classpath 上可用时, Spring Boot 可以配置ConnectionFactory. 如果存在代理,则会自动启动并配置嵌入式代理(前提是未通过配置指定代理 URL,并且未在配置中禁用嵌入式代理)。spring-doc.cadn.net.cn

如果您使用spring-boot-starter-activemq,提供了连接到 ActiveMQ “Classic” 实例所需的依赖项,以及与 JMS 集成的 Spring 基础架构。 添加org.apache.activemq:activemq-broker允许您使用嵌入式代理。

ActiveMQ “Classic” 配置由spring.activemq.*.spring-doc.cadn.net.cn

如果activemq-broker位于 Classpath 上,则 ActiveMQ “Classic” 会自动配置为使用 VM 传输,该传输将启动嵌入在同一 JVM 实例中的代理。spring-doc.cadn.net.cn

您可以通过配置spring.activemq.embedded.enabled属性,如以下示例所示:spring-doc.cadn.net.cn

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

如果您配置代理 URL,嵌入式代理也将被禁用,如以下示例所示:spring-doc.cadn.net.cn

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”文档以了解更多信息。spring-doc.cadn.net.cn

默认情况下,CachingConnectionFactory包装本机ConnectionFactory具有合理的设置,您可以通过spring.jms.*:spring-doc.cadn.net.cn

spring.jms.cache.session-cache-size=5
spring:
  jms:
    cache:
      session-cache-size: 5

如果您更愿意使用原生池,可以通过向org.messaginghub:pooled-jms并配置JmsPoolConnectionFactory因此,如以下示例所示:spring-doc.cadn.net.cn

spring.activemq.pool.enabled=true
spring.activemq.pool.max-connections=50
spring:
  activemq:
    pool:
      enabled: true
      max-connections: 50
ActiveMQProperties了解更多支持的选项。 您还可以注册任意数量的 bean 来实现ActiveMQConnectionFactoryCustomizer以获取更高级的自定义。

默认情况下,ActiveMQ “Classic” 会创建一个目标(如果尚不存在),以便根据提供的名称解析目标。spring-doc.cadn.net.cn

ActiveMQ Artemis 支持

Spring Boot 可以自动配置ConnectionFactory当它检测到 ActiveMQ Artemis 在 Classpath 上可用时。 如果存在代理,则会自动启动并配置嵌入式代理(除非已明确设置 mode 属性)。 支持的模式包括embedded(明确表示需要一个嵌入式代理,如果代理在 Classpath 上不可用,则应该发生错误)和native(要使用nettytransport 协议)。 配置后者时, Spring Boot 会配置一个ConnectionFactory连接到使用默认设置在本地计算机上运行的代理。spring-doc.cadn.net.cn

如果您使用spring-boot-starter-artemis,提供了连接到现有 ActiveMQ Artemis 实例所需的依赖项,以及与 JMS 集成的 Spring 基础架构。 添加org.apache.activemq:artemis-jakarta-server添加到您的应用程序中,允许您使用嵌入式模式。

ActiveMQ Artemis 配置由spring.artemis.*. 例如,您可以在application.properties:spring-doc.cadn.net.cn

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"

在嵌入代理时,您可以选择是否要启用持久性并列出应可用的目标。 这些可以指定为逗号分隔的列表,以便使用默认选项创建它们,或者您可以定义 bean 类型的JMSQueueConfigurationTopicConfiguration,分别用于高级队列和主题配置。spring-doc.cadn.net.cn

默认情况下,CachingConnectionFactory包装本机ConnectionFactory具有合理的设置,您可以通过spring.jms.*:spring-doc.cadn.net.cn

spring.jms.cache.session-cache-size=5
spring:
  jms:
    cache:
      session-cache-size: 5

如果您更愿意使用本机池,可以通过添加对org.messaginghub:pooled-jms并配置JmsPoolConnectionFactory因此,如以下示例所示:spring-doc.cadn.net.cn

spring.artemis.pool.enabled=true
spring.artemis.pool.max-connections=50
spring:
  artemis:
    pool:
      enabled: true
      max-connections: 50

ArtemisProperties以获取更多支持的选项。spring-doc.cadn.net.cn

不涉及 JNDI 查找,目标是根据其名称解析的,使用name属性或通过配置提供的名称。spring-doc.cadn.net.cn

使用 JNDI ConnectionFactory

如果您在应用程序服务器中运行应用程序,则 Spring Boot 会尝试查找 JMSConnectionFactory通过使用 JNDI。 默认情况下,java:/JmsXAjava:/XAConnectionFactorylocation 进行检查。 您可以使用spring.jms.jndi-nameproperty (如果需要指定备用位置),如以下示例所示:spring-doc.cadn.net.cn

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

发送消息

Spring的JmsTemplate是自动配置的,你可以将其直接自动连接到你自己的 bean 中,如以下示例所示:spring-doc.cadn.net.cn

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可以以类似的方式注射。 如果DestinationResolverMessageConverterbean 时,它会自动关联到自动配置的JmsTemplate.

接收消息

当 JMS 基础架构存在时,任何 bean 都可以使用@JmsListener以创建侦听器终端节点。 如果没有JmsListenerContainerFactory,则会自动配置默认 1 个。 如果DestinationResolver一个MessageConverterExceptionListenerbean,它们会自动与默认工厂相关联。spring-doc.cadn.net.cn

在大多数情况下,应针对本机配置消息侦听器容器ConnectionFactory. 这样,每个侦听器容器都有自己的连接,这就赋予了它在本地恢复方面的全部责任。 自动配置使用ConnectionFactoryUnwrapper从自动配置的 Connection Factory 中解包本机连接工厂。spring-doc.cadn.net.cn

auto-configuration 仅解包CachedConnectionFactory.

默认情况下,默认工厂是事务性的。 如果您在JtaTransactionManager存在,则默认情况下它与侦听器容器相关联。 如果没有,则sessionTransacted标志。 在后一种情况下,您可以通过添加@Transactional在你的侦听器方法(或其委托)上。 这可确保在本地事务完成后确认传入消息。 这还包括发送已在同一 JMS 会话上执行的响应消息。spring-doc.cadn.net.cn

以下组件在someQueue目的地:spring-doc.cadn.net.cn

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?) {
		// ...
	}

}
请参阅@EnableJmsAPI 文档了解更多详情。

如果您需要创建更多JmsListenerContainerFactory实例,或者如果您想覆盖默认值,Spring Boot 会提供DefaultJmsListenerContainerFactoryConfigurer,可用于初始化DefaultJmsListenerContainerFactory的设置与自动配置的设置相同。spring-doc.cadn.net.cn

例如,以下示例公开了另一个工厂,该工厂使用特定的MessageConverter:spring-doc.cadn.net.cn

import jakarta.jms.ConnectionFactory;

import org.springframework.boot.autoconfigure.jms.DefaultJmsListenerContainerFactoryConfigurer;
import org.springframework.boot.jms.ConnectionFactoryUnwrapper;
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.autoconfigure.jms.DefaultJmsListenerContainerFactoryConfigurer
import org.springframework.boot.jms.ConnectionFactoryUnwrapper
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-annotated 方法,如下所示:spring-doc.cadn.net.cn

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?) {
		// ...
	}

}