用于实现 JMS 消息传送的对象在编程域中基本保持不变:连接工厂、连接、会话、生成方、使用方、消息和目的地。图 2–5 中显示了这些对象。图中从连接工厂对象开始,自上而下地显示对象是如何派生出来的。
显示的连接工厂和目的地这两类对象驻留在对象存储库中。这是为了强调通常将这些对象作为受管理对象来创建、配置和管理。我们假定本章中的连接工厂和目的地都是以管理方式(而不是以编程方式)创建的。
表 2–2 总结了发送和接收消息所需的步骤。请注意,步骤 1 到 6 对于发送者和接收者来说是相同的。
表 2–2 生成和使用消息
生成消息 |
使用消息 |
---|---|
1. 管理员创建连接工厂受管理对象。 |
|
2. 管理员创建物理目的地以及引用该目的地的受管理对象。 |
|
3. 客户端通过 JNDI 查找获得连接工厂对象。 |
|
4. 客户端通过 JNDI 查找获得目的地对象。 |
|
5. 客户端创建连接并设置特定于此连接的任何属性。 |
|
6. 客户端创建会话并设置用于决定消息传送可靠性的属性。 |
|
7. 客户端创建消息生成方 |
客户端创建消息使用方 |
8. 客户端创建消息。 |
客户端建立连接。 |
9. 客户端发送消息。 |
客户端接收消息。 |
下面各节介绍生成方和使用方使用的对象:连接、会话、消息和目的地。之后,我们将通过说明消息的生成和使用来完成对 JMS 对象的介绍。
客户端使用连接工厂对象 (ConnectionFactory) 创建连接。连接对象 (Connection) 表示客户端与代理之间的活动连接。它使用在默认情况下启动或者由管理员为该客户端明确启动的底层连接服务。
创建连接时会分配通信资源并对客户端进行验证。这是一个相当重要的对象,大多数客户端均使用一个连接来完成所有的消息传送。连接支持并发使用:一个连接可由任意数量的生成方和使用方共享。
创建连接工厂时,可通过设置它的属性来配置从它派生的所有连接的行为。对于 Message Queue,这些设置可指定以下信息:
代理所在主机的名称、需要的连接服务以及客户端用于访问该服务的端口。
连接失败时应如何处理与代理的自动重新连接。(如果连接断开,此功能会将客户端重新连接到同一个代理或另一个代理。但不保证进行数据故障转移:如果重新连接到不同代理,持久性消息及其他状态信息可能会丢失。)
尝试进行连接的用户的默认名称和密码。如果连接时未指定密码,则该信息用于验证用户和授权操作。
如何管理代理与客户端运行时环境之间的控制消息和有效负荷消息的流动。
可以在用于启动客户端应用程序的命令行上覆盖连接工厂属性。还可以通过设置任意给定连接的属性来覆盖该连接的属性。
可使用连接对象来创建会话对象,从而设置异常侦听器或者获得 JMS 版本及提供者信息。
如果连接代表客户端与代理之间的通信渠道,则会话标记客户端与代理之间的单次对话。会话对象主要用于创建消息、消息生成方和消息使用方。创建会话时,通过多个确认选项或通过事务来配置可靠传送。有关详细信息,请参见可靠消息传送。
根据 JMS 规范,会话是生成和使用消息的单线程上下文。可以为一个会话创建多个消息生成方和使用方,但只能顺次使用它们。Java 客户端和 C 客户端的线程实现稍有不同。有关线程实现与限制的其他信息,请参考相应的开发者指南。
还可以使用会话对象来完成以下任务:
创建和配置临时主题和队列,它们将用作请求-回复模式的一部分。请参见请求-回复模式。
支持事务处理。
定义生成或使用消息的顺序。
消息由三部分组成:消息头、属性和主体。必须了解此结构,才能正确编写消息和配置某些消息传送行为。
消息头是每条 JMS 消息所必需的。消息头包含十个预定义字段,表 2–3 中列出并介绍了这些字段。
表 2–3 JMS 定义的消息头
头字段 |
描述 |
---|---|
在 0(低)到 9(高)的范围内指定消息的优先级。(默认情况下由提供者设置,也可以由客户端为生成方或为单独的消息显式设置。) |
|
从表中可以看出,消息头字段有多种用途:标识消息、配置消息的路由以及提供有关消息处理的信息等。
其中最重要的字段之一 JMSDeliveryMode,用于决定消息传送的可靠性。该字段指示一条消息是否为持久性消息。
部分消息头字段由提供者(代理或客户端运行时环境)设置,其他头字段则由客户端设置。消息生成方可能需要配置头字段值,才能实现某些消息传送行为;消息使用方可能需要读取头字段值,才能了解消息的路由方式以及可能需要对它执行哪些进一步处理。
头字段(JMSDeliveryMode、JMSExpiration 和 JMSPriority)可以在三个不同的级别上进行设置:
对于通过从连接工厂派生的每个连接发出的消息。
对于生成的每条消息。
对于特定消息生成方发出的所有消息。
如果这些字段在多于一个级别上进行设置,则为连接工厂设置的值将覆盖为单条消息设置的值;为给定消息设置的值将覆盖为消息生成方设置的值。
消息头字段的固定名称因语言实现而异。有关详细信息,请参见《Sun Java System Message Queue 3.7 UR1 Developer’s Guide for Java Clients》或《Sun Java System Message Queue 3.7 UR1 Developer’s Guide for C Clients》。
消息还可以包含称为属性的可选头字段,这类字段以属性名/属性值对的形式来指定。客户端和提供者可以使用属性来扩展消息头,并可以在其中包含有助于客户端或提供者标识和处理消息的任何信息。通过消息属性,接收客户端可以只传送符合给定标准的消息。例如,使用方客户端可能请求获得有关新泽西州兼职雇员工资单的消息。提供者将不会传送不符合指定标准的消息。
JMS 规范定义了九个标准属性。其中某几个属性由客户端设置,另外几个由提供者设置。属性的名称以保留字符 "JMSX" 开头。客户端或提供者可以使用这些属性决定消息的发送者、消息的状态以及消息传送的频率和时间。这些属性有助于提供者提供路由消息和诊断信息。
Message Queue 也定义消息属性,它们用于标识压缩消息以及在无法传送消息时应如何处理消息。有关详细信息,请参见《Sun Java System Message Queue 3.7 UR1 Developer’s Guide for Java Clients》中的“Managing Message Size”。
消息主体包含客户端需要交换的数据。
JMS 消息类型决定了主体可以包含哪些内容以及使用方应如何处理主体,如表 2–4 中所指定的那样。Session 对象包含各类消息主体的创建方法。
表 2–4 消息主体类型
类型 |
描述 |
---|---|
主体中包含 Java 基元值流的消息。它的填充和读取均按顺序进行。 |
|
主体中包含一组名/值对的消息。没有定义条目顺序。 |
|
主体中包含 Java 字符串的消息,例如 XML 消息。 |
|
主体中包含序列化 Java 对象的消息。 |
|
主体中包含连续字节流的消息。 |
|
包含消息头和属性但不包含主体的消息。 |
Java 客户端可以对属性进行设置,使客户端运行时环境压缩要发送的消息的主体。而使用方一端的 Message Queue 运行时环境会在传送消息前先解压缩该消息。