Java 消息传送服务规范最初的开发目的是为了使 Java 应用程序能够访问现有 MOM 系统。引入该规范之后,它已被许多现有的 MOM 供应商采用并且已经凭借自身的功能实现为异步消息传送系统。
在创建 JMS 规范时,设计者希望融合现有消息传送系统的精髓。这包括:
路由和传送消息的消息传送提供者的概念
不同的消息传送模式或域,例如点对点消息传送和发布/订阅消息传送
用于接收同步和异步消息的工具
对可靠消息传送的支持
常见消息格式,例如流、文本和字节
供应商通过提供一个 JMS 提供者来实现 JMS 规范,该提供者由实现 JMS 接口的库、消息的路由和传送功能以及用来管理、监视和调整消息传送服务的管理工具组成。路由和传送功能可以由集中式消息服务器或代理来执行,也可以通过每个客户端运行时环境的功能来实现。
同样,JMS 提供者可以扮演多种角色:可以创建为独立产品或大型分布式运行时环境系统中的嵌入式组件。作为独立产品时,它可以用于定义企业应用程序集成系统的主干;在嵌入到应用服务器中时,它可以支持组件间消息传送。例如,J2EE 使用 JMS 提供者实现消息驱动 Bean 并允许 EJB 组件发送和接收消息。
如果创建了包含现有系统所有功能的标准,则用户很难了解并实现通过此标准建立的系统。而 JMS 定义了消息传送概念和功能所具有的共同特点。从而使这种标准更易于掌握,并最大限度地提高了 JMS 应用程序在 JMS 提供者之间的可移植性。需要强调的一点是,JMS 是 API 标准,而不是协议标准。将 JMS 客户端从一个供应商移动到另一个供应商是很容易的。但是不同的 JMS 供应商之间通常不能相互直接通信。
下一节将介绍 JMS 规范定义的基本对象和消息传送模式。
为了发送或接收消息,JMS 客户端必须先连接到 JMS 提供者(该提供者通常作为消息代理实现):此连接在客户端与代理之间打开一个通信通道。接下来,客户端必须设置一个用来创建、生成和使用消息的会话。可以将该会话视为定义客户端与代理之间的特定对话的消息流。客户端本身就是消息生成方和/或消息使用方。消息生成方向代理所管理的目的地发送一条消息。消息使用方访问该目的地以使用此消息。该消息包括消息头、属性(可选)和主体。消息主体用来保存数据;消息头中包含代理路由和管理消息所需的信息;属性可以由客户端应用程序或提供者定义,以满足处理消息的需要。连接、会话、目的地、消息、生成方和使用方是构成 JMS 应用程序的基本对象。
通过这些基本对象,客户端应用程序可以两种消息传送模式(或域)发送和接收消息。图 1–4 对此进行了说明。
客户端 A 和 B 是消息生成方,它们通过两种不同类型的目的地向客户端 C、D 和 E 发送消息。
客户端 A、C 和 D 之间的消息传送说明了点对点模式。客户端使用此模式向队列目的地发送一条消息,只有一个接收者能够从该目的地获得该消息。访问该目的地的其他任何接收者都不能获得该消息。
客户端 B、E 和 F 之间的消息传送说明了发布/订阅模式。客户端使用此广播模式向主题目的地发送一条消息,任意数量的使用方订户都可以从该目的地检索此消息。每个订户都获得此消息的一个副本。
任何域中的消息使用方都可以选择同步或异步获取消息。同步使用方通过显式调用来检索消息;异步使用方则指定一个回调方法,将调用该回调方法来传递待处理的消息。使用方还可以通过为传入消息指定选择标准来过滤消息。
JMS 规范创建了一个标准,该标准结合了现有 MOM 系统的许多元素,但并不包含所有的可能元素。相反,它试图设置一个可扩展的方案来兼顾不同元素之间的区别并适应将来的发展。JMS 的很多消息传送元素都需要各个提供者来定义和实现。其中包括负载平衡、标准错误消息、管理 API、安全性、底层线路协议以及消息存储库。下一节Message Queue:元素和功能将介绍 Message Queue 如何实现其中的很多元素及其如何扩展 JMS 规范。
JMS 未完整定义的两个消息传送元素是连接工厂和目的地。尽管这些元素是 JMS 编程模型中的基础元素,但在提供者定义和管理这些对象的方式上,存在许多现有的和预期的区别,以致于不可能也不值得创建一个公共的定义。因此,这两个对象通常使用管理工具来创建和配置,而不是以编程方式来创建。它们随后将存储在对象存储库中,JMS 客户端可以通过标准的 JNDI 查找功能来访问它们。
连接工厂受管理对象用于生成客户端与代理的连接。它们封装特定于提供者的信息,这些信息控制消息传送行为的某些方面:连接处理、客户端标识、消息头覆盖、可靠性和流控制等。每个源自给定连接工厂的连接都展示出为该工厂配置的行为。
目的地受管理对象用于引用代理中的物理目的地。它们封装特定于提供者的命名(地址-语法)约定,并指定在其中使用目的地的消息传送域:队列或主题。
JMS 客户端不需要查找受管理的对象,它们可以通过编程的方式创建这些对象(随后这些对象存储在代理的内存中)。要快速建立原型,最方便的方法可能是以编程方式创建这些对象。但是,如果要在生产环境中部署,则在中心系统信息库中查找受管理对象会更便于控制和管理消息传送行为:
通过对连接工厂对象使用管理对象,管理员可以通过重新配置这些对象来调整消息传送性能。不必重新编码即可改善性能。
通过对物理目的地使用管理对象,管理员可以通过要求客户端访问这些预配置的对象来控制这些目的地在代理上的扩散。
受管理对象使开发者无需了解特定于提供者的实现详细信息,而允许将他们针对某个提供者开发的代码在无需更改或只需稍作更改的情况下移植到其他提供者。
如图 1–5 中所示,受管理对象的使用是基本 JMS 应用程序图中的最后一项关键技术。
图 1–5 显示消息生成方和消息使用方如何使用目的地受管理对象来访问对应于该对象的物理目的地。带编号的步骤是管理员和客户端应用程序在使用此机制发送和接收消息时需要执行的操作。