2.1 概述

本章描述基于消息的应用的环境和JMS在环境中扮演的角色。

2.2 什么是JMS应用

JMS应用由以下部分组成:

• JMS客户端——发送和接收消息的Java语言程序。

• 非JMS客户端——使用消息系统的本地客户端API而不是JMS 的API,如果应用先于JMS,那么它很可能既包含JMS又包含非JMS客户端。

• 消息——每个应用定义一系列的消息,这些消息用于在客户端之间交换信息。

• JMS提供商——它是一个消息系统,它实现了JMS以及其他的完整消息产品所需要的管理和控制功能。

• 被管理的对象——被管理的对象是预先配置好的JMS对象,它由管理员为客户端使用而创建。

2.3 管理

期望JMS提供商和它们的后台消息技术有大的区别。也期望在如何安装和管理提供商的系统也有大的区别。

如果JMS客户端是可移植的,那么他们必须与提供商专有的方面隔离开来。通过定义JMS 被管理的对象来做到隔离,这些对象由提供商的管理员创建和客户化,接下来由客户端使用。通过JMS 接口来使用它们的客户端是可移植的。管理员使用提供商专有的工具来创建它们。

有两种类型的JMS被管理对象:

• ConnectionFactory——这个对象用于客户端来创建和提供商的连接。

• Destination——这个对象用于客户端来指定发送消息的目的地,也是接收消息的来源。

被管理对象被管理员放置在JNDI命名空间。JMS客户端通常在它的文档中注上它要求的JMS被管理对象和这些对象的JNDI 名字应当如何提供给它。

2.4 两种消息风格

JMS应用既可以使用PTP风格又可以使用Pub/Sub 消息风格,在后面的章节中会有更详细的描述。应用也可以将两种风格组合到一个应用中。消息的这两种风格常被称为消息域。JMS 提供了这两种消息域,因为它们代表了两种通用的消息模型。

当使用JMS API时,开发人员可以使用两种消息模型的接口和方法。当使用接口时,消 息系统的行为可能会稍有不同,因为两种消息域有不同的语义。这些语义的差别在第5章“JMS点对点模型”和第6章“JMS 发布/订阅模型”中描述。

2.5 JMS接口

JMS基于一系列通用的消息概念。每个JMS消息域—PTP和Pub/Sub—也为这些概念定义了各自的接口集。

表 2.1. PTP和Pub/Sub 接口的关系

JMS 公共接口PTP 专有接口Pub/Sub 专有接口
ConnectionFactory QueueConnectionFactory TopicConnectionFactory
Connection QueueConnection TopicConnection
Destination Queue Topic
Session QueueSession TopicSession
MessageProducer QueueSender TopicPublisher
MessageConsumerQueueReceiver,QueueBrowserTopicConsumer

JMS通用接口提供了一个独立于PTP和Pub/Sub消息域的域视图。鼓励JMS客户端程序员使用这些接口来创建他们的客户端程序。

下面列出了这些JMS概念的简要定义。参见第4章“JMS通用工具”来详细了解这些概念。

对于两种消息域的差别的详细内容,参见第5章“JMS点对点模型”和第6章“JMS发布/订阅模型”。

• ConnectionFactory——客户端使用这个被管理对象来创建一个Connection。

• Connection——一个到JMS提高商的活动连接。

• Destination——封装了消息目的地标识的被管理对象。

• Session——一个用于发送和接收消息的单线程上下文。

• MessageProducer——一个由Session创建用于往目的地发送消息的对象。

• MessageConsumer——一个由Session创建用于接收发送到目的地的消息的对象。

在这个文档中使用的术语“消费”是指通过JMS客户端接收消息;也就是说,一个JMS 提供商已经收到一个消息并将它给了它的客户端。由于JMS支持同步和异步接收消息,因此术语“消费”在不需要区分它们的时候使用。术语“生产”用作发送消息的最通用的术语。它指给予JMS提供商一个消息以转发到一个目的地。

2.6 开发一个JMS应用

广义的讲,一个JMS应用是一个或多个交换消息的JMS客户端。应用也涉及非JMS客户端;但是,这些非JMS客户端使用JMS 提供商的本地API而不是JMS的API。一个JMS应用可以被架构和部署为一个单元。在许多情况下,JMS客户端是被逐渐增加到线程的应用中的。应用使用的消息定义可以来源于JMS,或者他们可能已经由应用的非JMS部分定义了。

2.6.1 开发一个JMS客户端

典型的JMS客户端执行下面的JMS设置过程:

• 使用JNDI来发现ConnectionFactory对象。

• 使用JNDI来发现一个或多个Desitination对象。

• 使用ConnectionFactory来创建一个具有消息转发约束的JMS Connection。

• 使用Connection来创建一个或多个JMS Session。

• 使用Session和Destination来创建需要的MessageProducer和MessageConsumer。

• 告诉Connection开始转发消息。

此时,客户端有了生产和消费消息的基本的JMS设置。

2.7 安全

JMS没有提供控制或配置消息完整或消息私密的特性。

这期望由JMS提供商来提供。也期望由提供商专有的管理工具来配置这些服务。客户 端将得到正确的安全配置作为他们使用的被管理对象的一部分。

2.8 多线程

JMS已经要求它的所有对象都支持并发誓要。由于支持并非访问通常会增加一些成本和复杂性,所以JMS 限制了那些很自然要被多线程客户端并发访问的对象的要求。其他的都被设计成在一个时间只能被一个逻辑线程访问。

JMS对象支持并发使用
Destination YES
ConnectionFactory YES
Connection YES
Session NO
MessageProducer NO
MessageConsumer NO

JMS定义了一些特殊的规则来限制Session的并发使用。由于他们要求比在这里呈现的更多的JMS 知识,所以他们将在后面描述。这里我们将描述他们必须遵守的基本原理。有两个原因要限制并发访问Session。第一个,Session是支持事务的JMS实体。实现多 线程的事务是非常困难的。第二,Session支持异步的消费消息。重要的是JMS不要求用于 消费异步消息的客户端代码有处理多个并发的消息的能力。另外,如果Session被设置有多个异步的消费者,那么不强迫客户端处理这些并发执行的分散的消费者。这些约束使得通常的客户端更加容易地使用JMS。更专业的客户端可以通过使用多个会话来获得他们期望的并非性。

2.9 触发式客户端

某些客户端被设计成被周期性的唤醒来处理等待它们的消息。一个基于消息的应用触发 机制常和客户端的风格一起使用。触发器通常是等待消息的起点,等等。JMS没有提供触发客户端执行的机制。某些提供商可以通过它们的管理工具提供这样的触发机制。

2.10 请求/回复

JMS提供了JMSReplyTo消息头字段来指定回复的消息应当被发送到的目的地。回复的JMSCorrelationID 头字段可以被用于引用原始的请求。参见3.4章节“消息头字段”了解详细信息。

另外,JMS提供了创建临时队列和主题的功能,它可以用作回复的唯一目的地。企业消息产品支持许多请求/回复风格,从简单的“一个消息请求产生一个消息回复” 到“一个消息请求产生一串回复,回复消息来自多个应答者”。JMS不仅架构了一个特定的 请求/回复抽象,而且提供了基本的工具,许多企业消息产品可以基于它来构建。

为了方便,JMS为PTP和Pub/Sub域定义了请求/响应帮助类(这些类用JMS实现),它实现了请求/回复的基本形式。JMS提供商和客户端可以提供更加专业的实现。