|
对于最新稳定版本,请使用Spring Framework 7.0.1! |
使用 Spring JMS
本节介绍如何使用Spring的JMS组件。
用Jms模板
这Jms模板类是JMS核心包的核心类。它简化了
使用JMS,因为它负责发送或
同步接收消息。
使用以下代码的代码Jms模板只需实现回调接口以实现
一份明确定义的高层合同。这消息创建器回调接口创建
当收到会期由调用代码提供的Jms模板.自
允许对 JMS API 进行更复杂的使用,会话回调提供
JMS 会话,以及制片人回应揭露了会期和消息制作人双。
JMS API 提供了两种发送方法,一种采用传输模式、优先级,
以及作为服务质量(Qos)参数的存活时间,且不接受服务质量
参数并使用默认值。因为Jms模板拥有许多发送方法,
设置QOS参数已作为豆属性暴露为
避免发送方法数量重复。同样,超时值
同步接收呼叫通过使用setReceiveTimeout财产。
一些 JMS 提供者允许通过
配置连接工厂.这具有这样一个效果:调用消息制作人实例发送方法 (发送(目的地,消息消息))
使用与 JMS 规范中指定的不同的 QoS 默认值。挨次
为了提供对Qos值的一致管理,Jms模板因此,必须
特别启用了通过设置布尔属性来使用自身的Qos值isExplicitQosEnabled自true.
为了方便起见,Jms模板还暴露了一个基本的请求-回复作,允许
用于发送消息并等待临时队列的回复,该队列作为
手术。
实例Jms模板类在配置后是线程安全的。这是
重要,因为它意味着你可以配置一个实例Jms模板然后安全地将这个共享引用注入多个合作者中。存在
清晰,那个Jms模板是有状态的,因为它保持对连接工厂但这个状态不是会话状态。 |
截至 Spring Framework 4.1,JmsMessagingTemplate建在Jms模板并且与消息抽象进行了集成——即,org.springframework.messaging.Message.这样你就可以创建消息
用一种通用的方式发送。
连接
这Jms模板需要引用连接工厂.这连接工厂是 JMS 规范的一部分,作为使用 JMS 的入门点。它
客户端应用程序用作工厂,用于与JMS建立连接
提供 并封装了各种配置参数,其中许多是
提供商专属,如SSL配置选项。
在EJB中使用JMS时,厂商会提供JMS接口的实现
这样他们就能参与声明式事务管理和池化
连接和会谈。为了使用该实现,雅加达EE容器
通常要求你声明JMS连接工厂为resource-ref里面
EJB或servlet部署描述符。为了确保这些特性的使用,Jms模板在EJB内部,客户端应用程序应确保其引用
管理实施连接工厂.
缓存消息资源
标准API涉及创建许多中间对象。要发送消息, 执行以下“API”步进:
ConnectionFactory->Connection->Session->MessageProducer->send
在连接工厂以及发送运算,三中间
物体被创造和摧毁。为了优化资源使用并增加
Spring 提供了两种实现连接工厂.
用单一连接工厂
Spring 提供了连接工厂接口单一连接工厂,返回相同的结果连接在所有createConnection()呼叫并忽略接近().这对测试和
独立环境,使同一连接可以用于多个Jms模板这些调用可以跨越任意数量的交易。单一连接工厂引用了标准连接工厂这通常来自JNDI。
用缓存连接工厂
这缓存连接工厂扩展了 的功能单一连接工厂并且增加了缓存会期,消息制作人和消息消费者实例。
初始缓存大小设置为1.你可以使用sessionCacheSize属性到
增加缓存会话数量。注意实际缓存会话数
比这个数值大,因为会话是根据其确认模式缓存的,
因此最多可以有四个缓存会话实例(每个确认模式一个)
什么时候sessionCacheSize设置为1。消息制作人和消息消费者实例
在其拥有会话中缓存,同时考虑其独特属性
在缓存时,生产者和消费者的关系。MessageProducers 的缓存基于其
目的地。MessageConsumer 的缓存基于由目标键组成的键,选择器,
noLocal 配送标志,以及持久订阅名称(如果创建持久消费者)。
|
MessageProducers 和 MessageConsumers 用于临时队列和主题
(TemporaryQueue/TemporaryTopic)永远不会被缓存。不幸的是,WebLogic JMS 会发生
为了在其常规目的实现上实现临时队列/主题接口,
错误地表示其任何目的地都无法缓存。请换个连接
WebLogic 上的池/缓存,或自定义 |
目的地管理
目的地,作为连接工厂实例,是你可以存储的JMS管理对象
并在JNDI中取回。在配置Spring应用上下文时,你可以使用
JNDIJndiObjectFactoryBean工厂级或<jee:jndi-lookup>执行依赖性
对对象对JMS目的地的引用进行注入。然而,这种策略
如果应用中有大量目的地,或者
是JMS提供商独有的高级目的地管理功能。示例
这些高级目的地管理包括创建动态目的地或
支持目的地的层级命名空间。这Jms模板代表们
将目标名称解析为实现目的地解析器接口。动态目的地解析器是默认值
采用的实现Jms模板并支持解决动态目的地。一个JndiDestinationResolver同时也作为服务定位器
目的地包含在JNDI中,并可选择退回到以下行为动态目的地解析器.
JMS 应用中使用的目标通常仅在运行时才知晓,
因此,应用程序部署时无法通过行政方式创建。这是
通常是因为交互的系统组件之间存在共享的应用逻辑
这些在运行时根据已知的命名规范创建目的地。甚至
虽然动态目的地的创建并非JMS规范的一部分,但大多数
厂商已经提供了这一功能。动态目的地由用户自定义名称创建,
这使它们区别于临时目的地,且通常
未在JNDI注册。用于创建动态目的地的API因服务商而异
由于与目的地相关的属性是提供商专属的。
然而,厂商有时会做出的一个简单实现选择是
忽略JMS规范中的警告,采用该方法主题会议
createTopic(String topicName)或者队列会话 createQueue(String
queueName)创建带有默认目的地属性的新目的地的方法。取决于
关于提供商的实现,动态目的地解析器还可以创建
物理目的地,而不是只解决一个。
布尔性质pubSubDomain用于配置Jms模板跟
了解所使用的 JMS 域。默认情况下,该属性的值为
false,表示点对点域,队列,将被使用。此地产
(使用Jms模板) 通过 决定动态目的解析的行为
该系统的实现目的地解析器接口。
你也可以配置Jms模板默认目的地通过
财产默认目的地.默认目的地是发送和接收
这些作不指向特定目的地。
消息监听器容器
JMS 消息在 EJB 领域最常见的用途之一是驱动消息驱动
Beans(MDBs)。Spring 提供了一种以某种方式创建消息驱动 POJO(MDP)的解决方案
这不会将用户绑定到EJB容器。(详见异步接收:消息驱动POJOs
斯普林支持MDP的报道。)自 Spring Framework 4.1 起,端点方法可以
注释为@JmsListener—— 详情请参见注释驱动监听器端点。
消息监听器容器用于接收来自JMS消息队列的消息,
开车消息监听器那是注入其中的。监听器容器为
负责所有消息接收和调度的线程传输到监听器中
加工。消息监听器容器是MDP与
消息服务提供商负责注册接收消息和参与
事务、资源获取与释放、异常转换等等。这
它让你可以编写(可能比较复杂的)业务逻辑
与接收消息(并可能回复消息)相关,以及委托
框架中的样板JMS基础设施关注点。
Spring 有两个标准的 JMS 消息监听器容器,每个容器都包含 其专业功能集。
用SimpleMessageListenerContainer
这种消息监听器容器是两种标准类型中较简单的一种。它创造了
启动时固定数量的JMS会话和消费者通过以下方式注册监听者
标准JMSMessageConsumer.setMessageListener()方法,并保留给JMS。
提供者以执行听众回拨。该变体不支持动态适应
用于运行时需求或参与外部管理事务。
在兼容性方面,它非常贴近独立JMS的精神
但通常不兼容雅加达EE的JMS限制。
而SimpleMessageListenerContainer不允许外部参与
它支持原生JMS事务。要启用此功能,
你可以切换会谈交易旗帜变为true或者在XML命名空间中,设置承认归属为交易.听众抛出例外,然后由主讲
回滚,消息会被重新传达。或者,考虑使用CLIENT_ACKNOWLEDGE模式,在异常情况下也能重新交付,但
不使用交易会期实例,因此不包括其他任何实例会期事务协议中的作(如发送响应消息)。 |
默认AUTO_ACKNOWLEDGE模式并未提供适当的可靠性保证。
当监听器执行失败时(因为提供者会自动执行),消息可能会丢失
在监听者调用后确认每条消息,且无任何例外可传播至
提供者)或监听器容器关闭时(你可以通过设置来配置
这acceptMessagesWhileStopping旗帜)。确保使用交易会话,以防万一
可靠性需求(例如,可靠的队列处理和持久主题订阅)。 |
用DefaultMessageListenerContainer
大多数情况下会使用该消息监听器容器。与SimpleMessageListenerContainer,该容器变体允许动态适应
运行时需要并能够参与外部管理的事务。
当配置为JtaTransactionManager.因此,处理可能会利用 XA 事务
语义学。这个听众容器在低要求之间取得了良好的平衡,因为
JMS 提供者,高级功能(例如参与外部管理)
交易),以及与雅加达EE环境的兼容性。
你可以自定义容器的缓存等级。注意,当不启用缓存时, 每次消息接收都会创建一个新的连接和一个新的会话。结合这些 对于非持久订阅且负载较高,可能会导致消息丢失。一定要 在这种情况下,使用合适的缓存等级。
该容器在经纪人宕机时也具备可恢复的能力。默认情况下,
一个简单的退避实现每五秒重试一次。你可以具体说明
一种习俗退避实施更细致的恢复方案。看指数退让举个例子。
就像它的兄弟姐妹一样 (SimpleMessageListenerContainer),DefaultMessageListenerContainer支持本地JMS事务,并允许
自定义确认模式。如果符合你的情况,这非常值得
推荐优先于外部管理的交易——前提是你能接受
偶尔会发送重复消息,以防JVM失效。自定义重复消息
你的业务逻辑中的检测步骤可以涵盖此类情况——例如,
以企业实体存在检查或协议表检查的形式出现。
任何此类安排都比另一种方案高效得多:
通过配置 XA 事务来包裹整个处理过程(通过配置DefaultMessageListenerContainer带有JtaTransactionManager)以覆盖
JMS 消息的接收以及业务逻辑在你的
消息监听器(包括数据库作等)。 |
默认AUTO_ACKNOWLEDGE模式并未提供适当的可靠性保证。
当监听器执行失败时(因为提供者会自动执行),消息可能会丢失
在监听者调用后确认每条消息,且无任何例外可传播至
提供者)或监听器容器关闭时(你可以通过设置来配置
这acceptMessagesWhileStopping旗帜)。确保使用交易会话,以防万一
可靠性需求(例如,可靠的队列处理和持久主题订阅)。 |
事务管理
Spring带来了JmsTransactionManager它管理单个JMS的交易连接工厂.这使得JMS应用能够利用托管事务
Spring 的功能,详见数据访问章节的事务管理部分。
这JmsTransactionManager执行本地资源事务,绑定JMS
来自指定连接/会话对连接工厂回到那个话题。Jms模板自动检测此类事务资源并进行作
因此。
在雅加达的电气工程环境中,连接工厂连接池和会话实例,
因此这些资源在交易间高效地重复利用。在独立环境中,
使用 Spring 的单一连接工厂结果是共享的JMS连接跟
每个事务都有其独立的会期.或者,考虑用途
或是针对提供者的池化适配器,如 ActiveMQ 的PooledConnectionFactory类。
你也可以使用Jms模板其中JtaTransactionManager以及一个支持XA的JMS连接工厂用于执行分布式事务。注意,这需要
同时使用JTA事务管理器以及正确配置的XA连接工厂。
(请查阅你雅加达EE服务器或JMS提供商的文档。)
在托管和非托管事务环境中重复使用代码可能会让人感到困惑
当使用 JMS API 创建会期来自连接.这是因为
JMS API 只有一种工厂方法来创建会期,并且需要
交易和确认模式。在托管环境中,设置这些值为
环境事务基础设施的责任,因此这些价值观
被提供商的 JMS 连接封装器忽略。当你使用Jms模板在非管理环境中,你可以通过使用
性能会谈交易和sessionAcknowledgeMode.当你使用PlatformTransactionManager跟Jms模板模板总是被赋予
事务型JMS会期.