本节介绍如何使用 Spring 的 JMS 组件。
用JmsTemplate
该类是 JMS 核心包中的中心类。它简化了
使用 JMS,因为它在发送或
同步接收消息。JmsTemplate
仅使用 needs 实现回调接口的代码,这些回调接口提供
明确定义的高级合同。回调接口创建一个
当 中调用代码提供 时,消息 。自
允许更复杂地使用 JMS API,提供
JMS 会话,并公开 a 和 pair。JmsTemplate
MessageCreator
Session
JmsTemplate
SessionCallback
ProducerCallback
Session
MessageProducer
JMS API 公开了两种类型的发送方法,一种采用交付方式、优先级、
和生存时间作为服务质量 (QOS) 参数,并且不需要 QOS
参数并使用默认值。由于有很多发送方法,
将 QOS 参数设置为 Bean 属性
避免发送方法的数量重复。同样,超时值
同步接收调用是使用属性设置的。JmsTemplate
setReceiveTimeout
某些 JMS 提供程序允许通过
的配置。这样做的效果是,调用实例的方法 ()
使用的 QOS 缺省值与 JMS 规范中指定的缺省值不同。挨次
为了提供一致的 QOS 值管理,因此必须
通过将 boolean 属性设置为 ,专门启用以使用自己的 QOS 值。ConnectionFactory
MessageProducer
send
send(Destination destination, Message message)
JmsTemplate
isExplicitQosEnabled
true
为方便起见,还公开了一个基本的请求-答复操作,该操作允许
用于发送消息并等待作为
操作。JmsTemplate
一旦配置,该类的实例是线程安全的。这是
很重要,因为这意味着您可以配置 A 的单个实例,然后安全地将此共享引用注入到多个协作者中。成为
clear, the 是有状态的,因为它保持对 的引用,但此状态不是会话状态。JmsTemplate JmsTemplate JmsTemplate ConnectionFactory |
从 Spring Framework 4.1 开始,它建立在消息传递抽象之上并提供与消息传递抽象的集成——即 .这使您可以创建消息
以通用方式发送。JmsMessagingTemplate
JmsTemplate
org.springframework.messaging.Message
连接
需要引用 .它是 JMS 规范的一部分,用作使用 JMS 的入口点。它
被客户端应用程序用作工厂,以创建与 JMS 的连接
提供程序并封装各种配置参数,其中许多是
特定于供应商,例如 SSL 配置选项。JmsTemplate
ConnectionFactory
ConnectionFactory
在 EJB 中使用 JMS 时,供应商提供 JMS 接口的实现
以便它们可以参与声明性事务管理并执行池化
连接和会话。为了使用此实现,Jakarta EE 容器
通常要求您将 JMS 连接工厂声明为内部
EJB 或 servlet 部署描述符。为了确保在 EJB 内部使用这些功能,客户机应用程序应确保它引用了
的托管实现。resource-ref
JmsTemplate
ConnectionFactory
缓存消息资源
标准 API 涉及创建许多中间对象。要发送消息, 执行以下“API”演练:
ConnectionFactory->Connection->Session->MessageProducer->send
在操作和操作之间,有三个中间
对象被创建和销毁。优化资源使用并增加
性能,Spring 提供了两种实现。ConnectionFactory
Send
ConnectionFactory
用SingleConnectionFactory
Spring 提供了接口 的实现,该接口在所有调用中返回相同的值,并忽略对 的调用。这对于测试和
独立环境,以便同一连接可用于可能跨越任意数量的事务的多个调用。 引用通常来自 JNDI 的标准。ConnectionFactory
SingleConnectionFactory
Connection
createConnection()
close()
JmsTemplate
SingleConnectionFactory
ConnectionFactory
用CachingConnectionFactory
扩展了 、 和 实例的功能并添加了缓存。
初始缓存大小设置为 。您可以使用该属性来执行以下操作
增加缓存会话的数量。请注意,实际缓存的会话数
大于该数字,因为会话是根据其确认模式缓存的,
因此,最多可以有四个缓存会话实例(每种确认模式一个)
when 设置为 1。 和实例
缓存在它们所拥有的会话中,并且还考虑了唯一的属性
缓存时的生产者和消费者。MessageProducer 根据其
目的地。MessageConsumers 基于由 destination、selector、
noLocal 传递标志和持久订阅名称(如果创建持久使用者)。CachingConnectionFactory
SingleConnectionFactory
Session
MessageProducer
MessageConsumer
1
sessionCacheSize
sessionCacheSize
MessageProducer
MessageConsumer
MessageProducers 和 MessageConsumers,用于临时队列和主题
(TemporaryQueue/TemporaryTopic) 永远不会被缓存。不幸的是,WebLogic JMS 发生了
要在其常规目标实现上实现临时队列/主题接口,
错误地指示其任何目标都不能缓存。请使用其他连接
在 WebLogic 上进行池/缓存,或为 WebLogic 目的进行自定义。 |
目的地管理
作为实例,目标是可以存储的 JMS 托管对象
并在 JNDI 中检索。配置 Spring 应用程序上下文时,可以使用
JNDI 工厂类或执行依赖关系
注入对象对 JMS 目标的引用。但是,这种策略
如果应用程序中有大量目的地,或者如果有
是 JMS 提供程序独有的高级目标管理功能。示例
这种高级目的地管理包括创建动态目的地或
支持目标的分层命名空间。各位代表
将目标名称解析为实现接口的 JMS 目标对象。 是默认值
实现由解析动态目标使用并适应。还提供 A 作为服务定位器
包含在 JNDI 中的目标,并可选择回退到 中包含的行为。ConnectionFactory
JndiObjectFactoryBean
<jee:jndi-lookup>
JmsTemplate
DestinationResolver
DynamicDestinationResolver
JmsTemplate
JndiDestinationResolver
DynamicDestinationResolver
通常,JMS 应用程序中使用的目标仅在运行时才已知,并且
因此,在部署应用程序时无法以管理方式创建。这是
通常是因为交互的系统组件之间存在共享的应用程序逻辑
根据众所周知的命名约定在运行时创建目标。甚至
尽管动态目标的创建不是 JMS 规范的一部分,但大多数
供应商提供了此功能。使用用户定义的名称创建动态目标,
这使它们与临时目的地区分开来,并且通常是
未在JNDI注册。用于创建动态目标的 API 因提供商而异
到提供程序,因为与目标关联的属性是特定于供应商的。
但是,供应商有时会做出一个简单的实现选择,即
忽略 JMS 规范中的警告,并使用该方法或方法创建具有缺省目标属性的新目标。取决于
在供应商实现上,还可以创建一个
物理目标,而不是只解析一个。TopicSession
createTopic(String topicName)
QueueSession
createQueue(String
queueName)
DynamicDestinationResolver
boolean 属性用于配置
了解正在使用的 JMS 域。默认情况下,此属性的值为
false,表示要使用点对点域 。该属性
(使用者 ) 通过 确定动态目标解析的行为
接口的实现。pubSubDomain
JmsTemplate
Queues
JmsTemplate
DestinationResolver
您还可以通过
财产。默认目标为发送和接收
不引用特定目标的操作。JmsTemplate
defaultDestination
消息侦听器容器
在 EJB 世界中,JMS 消息最常见的用途之一是驱动消息驱动
豆类 (MDB)。Spring 提供了一种以某种方式创建消息驱动的 POJO (MDP) 的解决方案
这不会将用户绑定到 EJB 容器。(有关详细信息,请参阅异步接收:消息驱动的 POJO
覆盖 Spring 的 MDP 支持。从 Spring Framework 4.1 开始,端点方法可以
annotated with — 有关更多详细信息,请参阅注释驱动的侦听器端点。@JmsListener
消息侦听器容器用于接收来自 JMS 消息队列的消息,并且
驱动注入其中的。侦听器容器是
负责将消息接收和调度到侦听器的所有线程
加工。消息侦听器容器是 MDP 和
消息传递提供者,并负责注册接收消息,参与
事务、资源获取和释放、异常转换等。这
允许您编写(可能很复杂的)业务逻辑
与接收消息(并可能响应消息)和委托相关联
样板 JMS 基础结构对框架的关注。MessageListener
Spring 附带了两个标准的 JMS 消息侦听器容器,每个容器都带有 其专用功能集。
用SimpleMessageListenerContainer
此消息侦听器容器是两种标准风格中较简单的一种。它创造了
在启动时固定数量的 JMS 会话和使用者,使用
标准的 JMS 方法,并将其留给 JMS
提供程序来执行侦听器回调。此变体不允许动态适应
运行时需求或参与外部管理事务。
在兼容性方面,它非常接近独立 JMS 的精神
规范,但通常与 Jakarta EE 的 JMS 限制不兼容。MessageConsumer.setMessageListener()
虽然不允许外部参与
托管事务,它确实支持本机 JMS 事务。要启用此功能,
可以将标志切换到 ,或者在 XML 命名空间中将属性设置为 。从侦听器抛出的异常然后引导
回滚,并重新传递消息。或者,考虑使用模式,该模式在发生异常时也提供重新交付,但
不使用事务处理实例,因此在事务协议中不包含任何其他操作(例如发送响应消息)。SimpleMessageListenerContainer sessionTransacted true acknowledge transacted CLIENT_ACKNOWLEDGE Session Session |
默认模式不提供适当的可靠性保证。
当侦听器执行失败时,消息可能会丢失(因为提供程序会自动
在侦听器调用后确认每条消息,没有要传播到的异常
提供程序)或侦听器容器关闭时(可以通过设置
标志)。请确保使用事务处理的会话,以防出现以下情况:
可靠性需求(例如,可靠的队列处理和持久的主题订阅)。AUTO_ACKNOWLEDGE acceptMessagesWhileStopping |
用DefaultMessageListenerContainer
大多数情况下使用此消息侦听器容器。与此相反,此容器变体允许动态适应
满足运行时需求,并能够参与外部管理的事务。
当配置了 .因此,处理可能会利用 XA 事务
语义学。此侦听器容器在以下方面的低要求之间取得了良好的平衡
JMS 提供程序,高级功能(例如参与外部托管
事务),以及与 Jakarta EE 环境的兼容性。SimpleMessageListenerContainer
JtaTransactionManager
您可以自定义容器的缓存级别。请注意,当未启用缓存时, 为每个消息接收创建一个新连接和新会话。结合这个 使用高负载的非持久性订阅可能会导致消息丢失。确保 在这种情况下,请使用适当的缓存级别。
当代理关闭时,此容器还具有可恢复功能。默认情况下,
一个简单的实现每五秒重试一次。您可以指定
用于更细粒度恢复选项的自定义实现。有关示例,请参阅 ExponentialBackOff
。BackOff
BackOff
与它的同级 (SimpleMessageListenerContainer ) 一样,支持本机 JMS 事务并允许
自定义确认模式。如果对你的方案可行,这强烈
推荐而不是外部管理事务 - 也就是说,如果您可以忍受
在 JVM 死机的情况下偶尔会出现重复消息。自定义重复消息
业务逻辑中的检测步骤可以涵盖此类情况,例如,
以业务实体存在性检查或协议表检查的形式。
任何此类安排都比替代方案有效得多:
用 XA 事务包装您的整个处理(通过配置 ) 来覆盖
接收 JMS 消息以及执行业务逻辑
消息侦听器(包括数据库操作等)。DefaultMessageListenerContainer DefaultMessageListenerContainer JtaTransactionManager |
默认模式不提供适当的可靠性保证。
当侦听器执行失败时,消息可能会丢失(因为提供程序会自动
在侦听器调用后确认每条消息,没有要传播到的异常
提供程序)或侦听器容器关闭时(可以通过设置
标志)。请确保使用事务处理的会话,以防出现以下情况:
可靠性需求(例如,可靠的队列处理和持久的主题订阅)。AUTO_ACKNOWLEDGE acceptMessagesWhileStopping |
交易管理
Spring 提供了一个管理单个 JMS 事务的事务。这使 JMS 应用程序能够利用托管事务
Spring 的功能,如“数据访问”一章的“事务管理”部分所述。
执行本地资源事务,绑定 JMS
从指定到线程的连接/会话对。 自动检测此类事务性资源并操作
相应地在他们身上。JmsTransactionManager
ConnectionFactory
JmsTransactionManager
ConnectionFactory
JmsTemplate
在 Jakarta EE 环境中,池 Connection 和 Session 实例、
因此,这些资源可以在事务中有效地重用。在独立环境中,
在共享 JMS 中使用 Spring 的结果,使用
每笔交易都有自己独立的.或者,考虑使用
特定于提供程序的池适配器,例如 ActiveMQ 的类。ConnectionFactory
SingleConnectionFactory
Connection
Session
PooledConnectionFactory
您还可以与支持 XA 的 JMS 一起使用来执行分布式事务。请注意,这需要
使用 JTA 事务管理器以及正确配置的 XA 的 ConnectionFactory。
(查看 Jakarta EE 服务器或 JMS 提供程序的文档。JmsTemplate
JtaTransactionManager
ConnectionFactory
在托管和非托管事务环境中重用代码可能会令人困惑
使用 JMS API 从 .这是因为
JMS API 只有一个工厂方法来创建 ,并且它需要
事务和确认模式。在托管环境中,设置这些值是
环境事务基础设施的责任,因此这些价值
被供应商的 JMS Connection 包装器忽略。在非托管环境中使用 时,可以通过使用
properties 和 .当您使用 with 时,模板始终被赋予
事务性 JMS。Session
Connection
Session
JmsTemplate
sessionTransacted
sessionAcknowledgeMode
PlatformTransactionManager
JmsTemplate
Session