对于最新稳定版本,请使用Spring Framework 7.0.1spring-doc.cadn.net.cn

使用 Spring JMS

本节介绍如何使用Spring的JMS组件。spring-doc.cadn.net.cn

Jms模板

Jms模板类是JMS核心包的核心类。它简化了 使用JMS,因为它负责发送或 同步接收消息。spring-doc.cadn.net.cn

使用以下代码的代码Jms模板只需实现回调接口以实现 一份明确定义的高层合同。这消息创建器回调接口创建 当收到会期由调用代码提供的Jms模板.自 允许对 JMS API 进行更复杂的使用,会话回调提供 JMS 会话,以及制片人回应揭露了会期消息制作人双。spring-doc.cadn.net.cn

JMS API 提供了两种发送方法,一种采用传输模式、优先级, 以及作为服务质量(Qos)参数的存活时间,且不接受服务质量 参数并使用默认值。因为Jms模板拥有许多发送方法, 设置QOS参数已作为豆属性暴露为 避免发送方法数量重复。同样,超时值 同步接收呼叫通过使用setReceiveTimeout财产。spring-doc.cadn.net.cn

一些 JMS 提供者允许通过 配置连接工厂.这具有这样一个效果:调用消息制作人实例发送方法 (发送(目的地,消息消息)) 使用与 JMS 规范中指定的不同的 QoS 默认值。挨次 为了提供对Qos值的一致管理,Jms模板因此,必须 特别启用了通过设置布尔属性来使用自身的Qos值isExplicitQosEnabledtrue.spring-doc.cadn.net.cn

为了方便起见,Jms模板还暴露了一个基本的请求-回复作,允许 用于发送消息并等待临时队列的回复,该队列作为 手术。spring-doc.cadn.net.cn

实例Jms模板类在配置后是线程安全的。这是 重要,因为它意味着你可以配置一个实例Jms模板然后安全地将这个共享引用注入多个合作者中。存在 清晰,那个Jms模板是有状态的,因为它保持对连接工厂但这个状态不是会话状态。

截至 Spring Framework 4.1,JmsMessagingTemplate建在Jms模板并且与消息抽象进行了集成——即,org.springframework.messaging.Message.这样你就可以创建消息 用一种通用的方式发送。spring-doc.cadn.net.cn

连接

Jms模板需要引用连接工厂.这连接工厂是 JMS 规范的一部分,作为使用 JMS 的入门点。它 客户端应用程序用作工厂,用于与JMS建立连接 提供 并封装了各种配置参数,其中许多是 提供商专属,如SSL配置选项。spring-doc.cadn.net.cn

在EJB中使用JMS时,厂商会提供JMS接口的实现 这样他们就能参与声明式事务管理和池化 连接和会谈。为了使用该实现,雅加达EE容器 通常要求你声明JMS连接工厂为resource-ref里面 EJB或servlet部署描述符。为了确保这些特性的使用,Jms模板在EJB内部,客户端应用程序应确保其引用 管理实施连接工厂.spring-doc.cadn.net.cn

缓存消息资源

标准API涉及创建许多中间对象。要发送消息, 执行以下“API”步进:spring-doc.cadn.net.cn

ConnectionFactory->Connection->Session->MessageProducer->send

连接工厂以及发送运算,三中间 物体被创造和摧毁。为了优化资源使用并增加 Spring 提供了两种实现连接工厂.spring-doc.cadn.net.cn

单一连接工厂

Spring 提供了连接工厂接口单一连接工厂,返回相同的结果连接在所有createConnection()呼叫并忽略接近().这对测试和 独立环境,使同一连接可以用于多个Jms模板这些调用可以跨越任意数量的交易。单一连接工厂引用了标准连接工厂这通常来自JNDI。spring-doc.cadn.net.cn

缓存连接工厂

缓存连接工厂扩展了 的功能单一连接工厂并且增加了缓存会期,消息制作人消息消费者实例。 初始缓存大小设置为1.你可以使用sessionCacheSize属性到 增加缓存会话数量。注意实际缓存会话数 比这个数值大,因为会话是根据其确认模式缓存的, 因此最多可以有四个缓存会话实例(每个确认模式一个) 什么时候sessionCacheSize设置为1。消息制作人消息消费者实例 在其拥有会话中缓存,同时考虑其独特属性 在缓存时,生产者和消费者的关系。MessageProducers 的缓存基于其 目的地。MessageConsumer 的缓存基于由目标键组成的键,选择器, noLocal 配送标志,以及持久订阅名称(如果创建持久消费者)。spring-doc.cadn.net.cn

MessageProducers 和 MessageConsumers 用于临时队列和主题 (TemporaryQueue/TemporaryTopic)永远不会被缓存。不幸的是,WebLogic JMS 会发生 为了在其常规目的实现上实现临时队列/主题接口, 错误地表示其任何目的地都无法缓存。请换个连接 WebLogic 上的池/缓存,或自定义缓存连接工厂用于WebLogic的目的。spring-doc.cadn.net.cn

目的地管理

目的地,作为连接工厂实例,是你可以存储的JMS管理对象 并在JNDI中取回。在配置Spring应用上下文时,你可以使用 JNDIJndiObjectFactoryBean工厂级或<jee:jndi-lookup>执行依赖性 对对象对JMS目的地的引用进行注入。然而,这种策略 如果应用中有大量目的地,或者 是JMS提供商独有的高级目的地管理功能。示例 这些高级目的地管理包括创建动态目的地或 支持目的地的层级命名空间。这Jms模板代表们 将目标名称解析为实现目的地解析器接口。动态目的地解析器是默认值 采用的实现Jms模板并支持解决动态目的地。一个JndiDestinationResolver同时也作为服务定位器 目的地包含在JNDI中,并可选择退回到以下行为动态目的地解析器.spring-doc.cadn.net.cn

JMS 应用中使用的目标通常仅在运行时才知晓, 因此,应用程序部署时无法通过行政方式创建。这是 通常是因为交互的系统组件之间存在共享的应用逻辑 这些在运行时根据已知的命名规范创建目的地。甚至 虽然动态目的地的创建并非JMS规范的一部分,但大多数 厂商已经提供了这一功能。动态目的地由用户自定义名称创建, 这使它们区别于临时目的地,且通常 未在JNDI注册。用于创建动态目的地的API因服务商而异 由于与目的地相关的属性是提供商专属的。 然而,厂商有时会做出的一个简单实现选择是 忽略JMS规范中的警告,采用该方法主题会议 createTopic(String topicName)或者队列会话 createQueue(String queueName)创建带有默认目的地属性的新目的地的方法。取决于 关于提供商的实现,动态目的地解析器还可以创建 物理目的地,而不是只解决一个。spring-doc.cadn.net.cn

布尔性质pubSubDomain用于配置Jms模板跟 了解所使用的 JMS 域。默认情况下,该属性的值为 false,表示点对点域,队列,将被使用。此地产 (使用Jms模板) 通过 决定动态目的解析的行为 该系统的实现目的地解析器接口。spring-doc.cadn.net.cn

你也可以配置Jms模板默认目的地通过 财产默认目的地.默认目的地是发送和接收 这些作不指向特定目的地。spring-doc.cadn.net.cn

消息监听器容器

JMS 消息在 EJB 领域最常见的用途之一是驱动消息驱动 Beans(MDBs)。Spring 提供了一种以某种方式创建消息驱动 POJO(MDP)的解决方案 这不会将用户绑定到EJB容器。(详见异步接收:消息驱动POJOs 斯普林支持MDP的报道。)自 Spring Framework 4.1 起,端点方法可以 注释为@JmsListener—— 详情请参见注释驱动监听器端点spring-doc.cadn.net.cn

消息监听器容器用于接收来自JMS消息队列的消息, 开车消息监听器那是注入其中的。监听器容器为 负责所有消息接收和调度的线程传输到监听器中 加工。消息监听器容器是MDP与 消息服务提供商负责注册接收消息和参与 事务、资源获取与释放、异常转换等等。这 它让你可以编写(可能比较复杂的)业务逻辑 与接收消息(并可能回复消息)相关,以及委托 框架中的样板JMS基础设施关注点。spring-doc.cadn.net.cn

Spring 有两个标准的 JMS 消息监听器容器,每个容器都包含 其专业功能集。spring-doc.cadn.net.cn

SimpleMessageListenerContainer

这种消息监听器容器是两种标准类型中较简单的一种。它创造了 启动时固定数量的JMS会话和消费者通过以下方式注册监听者 标准JMSMessageConsumer.setMessageListener()方法,并保留给JMS。 提供者以执行听众回拨。该变体不支持动态适应 用于运行时需求或参与外部管理事务。 在兼容性方面,它非常贴近独立JMS的精神 但通常不兼容雅加达EE的JMS限制。spring-doc.cadn.net.cn

SimpleMessageListenerContainer不允许外部参与 它支持原生JMS事务。要启用此功能, 你可以切换会谈交易旗帜变为true或者在XML命名空间中,设置承认归属为交易.听众抛出例外,然后由主讲 回滚,消息会被重新传达。或者,考虑使用CLIENT_ACKNOWLEDGE模式,在异常情况下也能重新交付,但 不使用交易会期实例,因此不包括其他任何实例会期事务协议中的作(如发送响应消息)。
默认AUTO_ACKNOWLEDGE模式并未提供适当的可靠性保证。 当监听器执行失败时(因为提供者会自动执行),消息可能会丢失 在监听者调用后确认每条消息,且无任何例外可传播至 提供者)或监听器容器关闭时(你可以通过设置来配置 这acceptMessagesWhileStopping旗帜)。确保使用交易会话,以防万一 可靠性需求(例如,可靠的队列处理和持久主题订阅)。

DefaultMessageListenerContainer

大多数情况下会使用该消息监听器容器。与SimpleMessageListenerContainer,该容器变体允许动态适应 运行时需要并能够参与外部管理的事务。 当配置为JtaTransactionManager.因此,处理可能会利用 XA 事务 语义学。这个听众容器在低要求之间取得了良好的平衡,因为 JMS 提供者,高级功能(例如参与外部管理) 交易),以及与雅加达EE环境的兼容性。spring-doc.cadn.net.cn

你可以自定义容器的缓存等级。注意,当不启用缓存时, 每次消息接收都会创建一个新的连接和一个新的会话。结合这些 对于非持久订阅且负载较高,可能会导致消息丢失。一定要 在这种情况下,使用合适的缓存等级。spring-doc.cadn.net.cn

该容器在经纪人宕机时也具备可恢复的能力。默认情况下, 一个简单的退避实现每五秒重试一次。你可以具体说明 一种习俗退避实施更细致的恢复方案。看指数退让举个例子。spring-doc.cadn.net.cn

就像它的兄弟姐妹一样 (SimpleMessageListenerContainer),DefaultMessageListenerContainer支持本地JMS事务,并允许 自定义确认模式。如果符合你的情况,这非常值得 推荐优先于外部管理的交易——前提是你能接受 偶尔会发送重复消息,以防JVM失效。自定义重复消息 你的业务逻辑中的检测步骤可以涵盖此类情况——例如, 以企业实体存在检查或协议表检查的形式出现。 任何此类安排都比另一种方案高效得多: 通过配置 XA 事务来包裹整个处理过程(通过配置DefaultMessageListenerContainer带有JtaTransactionManager)以覆盖 JMS 消息的接收以及业务逻辑在你的 消息监听器(包括数据库作等)。
默认AUTO_ACKNOWLEDGE模式并未提供适当的可靠性保证。 当监听器执行失败时(因为提供者会自动执行),消息可能会丢失 在监听者调用后确认每条消息,且无任何例外可传播至 提供者)或监听器容器关闭时(你可以通过设置来配置 这acceptMessagesWhileStopping旗帜)。确保使用交易会话,以防万一 可靠性需求(例如,可靠的队列处理和持久主题订阅)。

事务管理

Spring带来了JmsTransactionManager它管理单个JMS的交易连接工厂.这使得JMS应用能够利用托管事务 Spring 的功能,详见数据访问章节的事务管理部分。 这JmsTransactionManager执行本地资源事务,绑定JMS 来自指定连接/会话对连接工厂回到那个话题。Jms模板自动检测此类事务资源并进行作 因此。spring-doc.cadn.net.cn

在雅加达的电气工程环境中,连接工厂连接池和会话实例, 因此这些资源在交易间高效地重复利用。在独立环境中, 使用 Spring 的单一连接工厂结果是共享的JMS连接跟 每个事务都有其独立的会期.或者,考虑用途 或是针对提供者的池化适配器,如 ActiveMQ 的PooledConnectionFactory类。spring-doc.cadn.net.cn

你也可以使用Jms模板其中JtaTransactionManager以及一个支持XA的JMS连接工厂用于执行分布式事务。注意,这需要 同时使用JTA事务管理器以及正确配置的XA连接工厂。 (请查阅你雅加达EE服务器或JMS提供商的文档。)spring-doc.cadn.net.cn

在托管和非托管事务环境中重复使用代码可能会让人感到困惑 当使用 JMS API 创建会期来自连接.这是因为 JMS API 只有一种工厂方法来创建会期,并且需要 交易和确认模式。在托管环境中,设置这些值为 环境事务基础设施的责任,因此这些价值观 被提供商的 JMS 连接封装器忽略。当你使用Jms模板在非管理环境中,你可以通过使用 性能会谈交易sessionAcknowledgeMode.当你使用PlatformTransactionManagerJms模板模板总是被赋予 事务型JMS会期.spring-doc.cadn.net.cn