此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Boot 3.4.3! |
JMS 公司
这ConnectionFactory
interface 提供了一种创建Connection
用于与 JMS 代理交互。
尽管 Spring 需要一个ConnectionFactory
要使用 JMS,您通常不需要自己直接使用它,而是可以依赖更高级别的消息传递抽象。
(有关详细信息,请参阅 Spring Framework 参考文档的相关部分。
Spring Boot 还自动配置了发送和接收消息所需的基础设施。
ActiveMQ “Classic” 支持
当 ActiveMQ “Classic” 在 Classpath 上可用时, Spring Boot 可以配置ConnectionFactory
.
如果存在代理,则会自动启动并配置嵌入式代理(前提是未通过配置指定代理 URL,并且未在配置中禁用嵌入式代理)。
如果您使用spring-boot-starter-activemq ,提供了连接到 ActiveMQ “Classic” 实例所需的依赖项,以及与 JMS 集成的 Spring 基础架构。
添加org.apache.activemq:activemq-broker 允许您使用嵌入式代理。 |
ActiveMQ “Classic” 配置由spring.activemq.*
.
如果activemq-broker
位于 Classpath 上,则 ActiveMQ “Classic” 会自动配置为使用 VM 传输,该传输将启动嵌入在同一 JVM 实例中的代理。
您可以通过配置spring.activemq.embedded.enabled
属性,如以下示例所示:
-
Properties
-
YAML
spring.activemq.embedded.enabled=false
spring:
activemq:
embedded:
enabled: false
如果您配置代理 URL,嵌入式代理也将被禁用,如以下示例所示:
-
Properties
-
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.*
:
-
Properties
-
YAML
spring.jms.cache.session-cache-size=5
spring:
jms:
cache:
session-cache-size: 5
如果您更愿意使用原生池,可以通过向org.messaginghub:pooled-jms
并配置JmsPoolConnectionFactory
因此,如以下示例所示:
-
Properties
-
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 可以自动配置ConnectionFactory
当它检测到 ActiveMQ Artemis 在 Classpath 上可用时。
如果存在代理,则会自动启动并配置嵌入式代理(除非已明确设置 mode 属性)。
支持的模式包括embedded
(明确表示需要一个嵌入式代理,如果代理在 Classpath 上不可用,则应该发生错误)和native
(要使用netty
transport 协议)。
配置后者时, Spring Boot 会配置一个ConnectionFactory
连接到使用默认设置在本地计算机上运行的代理。
如果您使用spring-boot-starter-artemis ,提供了连接到现有 ActiveMQ Artemis 实例所需的依赖项,以及与 JMS 集成的 Spring 基础架构。
添加org.apache.activemq:artemis-jakarta-server 添加到您的应用程序中,允许您使用嵌入式模式。 |
ActiveMQ Artemis 配置由spring.artemis.*
.
例如,您可以在application.properties
:
-
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"
在嵌入代理时,您可以选择是否要启用持久性并列出应可用的目标。
这些可以指定为逗号分隔的列表,以便使用默认选项创建它们,或者您可以定义 bean 类型的JMSQueueConfiguration
或TopicConfiguration
,分别用于高级队列和主题配置。
默认情况下,CachingConnectionFactory
包装本机ConnectionFactory
具有合理的设置,您可以通过spring.jms.*
:
-
Properties
-
YAML
spring.jms.cache.session-cache-size=5
spring:
jms:
cache:
session-cache-size: 5
如果您更愿意使用本机池,可以通过添加对org.messaginghub:pooled-jms
并配置JmsPoolConnectionFactory
因此,如以下示例所示:
-
Properties
-
YAML
spring.artemis.pool.enabled=true
spring.artemis.pool.max-connections=50
spring:
artemis:
pool:
enabled: true
max-connections: 50
看ArtemisProperties
以获取更多支持的选项。
不涉及 JNDI 查找,目标是根据其名称解析的,使用name
属性或通过配置提供的名称。
使用 JNDI ConnectionFactory
如果您在应用程序服务器中运行应用程序,则 Spring Boot 会尝试查找 JMSConnectionFactory
通过使用 JNDI。
默认情况下,java:/JmsXA
和java:/XAConnectionFactory
location 进行检查。
您可以使用spring.jms.jndi-name
property (如果需要指定备用位置),如以下示例所示:
-
Properties
-
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
can be injected in a similar manner.
If a DestinationResolver
or a MessageConverter
bean is defined, it is associated automatically to the auto-configured JmsTemplate
.
Receiving a Message
When the JMS infrastructure is present, any bean can be annotated with @JmsListener
to create a listener endpoint.
If no JmsListenerContainerFactory
has been defined, a default one is configured automatically.
If a DestinationResolver
, a MessageConverter
, or a ExceptionListener
beans are defined, they are associated automatically with the default factory.
In most scenarios, message listener containers should be configured against the native ConnectionFactory
.
This way each listener container has its own connection and this gives full responsibility to it in terms of local recovery.
The auto-configuration uses ConnectionFactoryUnwrapper
to unwrap the native connection factory from the auto-configured one.
The auto-configuration only unwraps CachedConnectionFactory
.
By default, the default factory is transactional.
If you run in an infrastructure where a JtaTransactionManager
is present, it is associated to the listener container by default.
If not, the sessionTransacted
flag is enabled.
In that latter scenario, you can associate your local data store transaction to the processing of an incoming message by adding @Transactional
on your listener method (or a delegate thereof).
This ensures that the incoming message is acknowledged, once the local transaction has completed.
This also includes sending response messages that have been performed on the same JMS session.
The following component creates a listener endpoint on the someQueue
destination:
-
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?) {
// ...
}
}
See the @EnableJms
API documentation for more details.
If you need to create more JmsListenerContainerFactory
instances or if you want to override the default, Spring Boot provides a DefaultJmsListenerContainerFactoryConfigurer
that you can use to initialize a DefaultJmsListenerContainerFactory
with the same settings as the one that is auto-configured.
For instance, the following example exposes another factory that uses a specific MessageConverter
:
-
Java
-
Kotlin
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
}
}
In the example above, the customization uses ConnectionFactoryUnwrapper
to associate the native connection factory to the message listener container the same way the auto-configured factory does.
Then you can use the factory in any @JmsListener
-annotated method as follows:
-
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?) {
// ...
}
}