RMI 应用概述

RMI 应用程序通常包含两个单独的程序,即服务器和 Client 端。典型的服务器程序会创建一些远程对象,使对这些对象的引用可访问,并 awaitClient 端调用这些对象上的方法。一个典型的 Client 端程序获取对服务器上一个或多个远程对象的远程引用,然后调用它们上的方法。 RMI 提供了一种机制,服务器和 Client 端通过该机制进行通信并来回传递信息。有时将这样的应用程序称为分布式对象应用程序。

分布式对象应用程序需要执行以下操作:

  • 查找远程对象. 应用程序可以使用各种机制来获取对远程对象的引用。例如,应用程序可以使用 RMI 的简单命名功能 RMI 注册表注册其远程对象。或者,应用程序可以传递和返回远程对象引用,作为其他远程调用的一部分。

  • 与远程对象通信. 远程对象之间的通信详细信息由 RMI 处理。对程序员而言,远程通信看起来类似于常规的 Java 方法调用。

  • 为要传递的对象加载类定义. 由于 RMI 允许来回传递对象,因此 RMI 提供了用于加载对象的类定义以及传输对象的数据的机制。

下图描绘了使用 RMI 注册表获取对远程对象的引用的 RMI 分布式应用程序。服务器调用注册表以将名称与远程对象关联(或绑定)。Client 端在服务器的注册表中通过其名称查找远程对象,然后在其上调用一个方法。该图还显示 RMI 系统使用现有的 Web 服务器在需要时从服务器到 Client 端以及从 Client 端到服务器为对象加载类定义。

RMI 系统使用现有的 Web 服务器,从服务到 Client 端以及从 Client 端到服务器进行通信

动态代码加载的优点

RMI 的核心和独特功能之一是,如果未在接收者的 Java 虚拟机中定义对象的类,则它可以下载该对象的类的定义。以前只能在单个 Java 虚拟机中使用的对象的所有类型和行为,都可以传输到另一个可能是远程的 Java 虚拟机。 RMI 按对象的实际类传递对象,因此将对象发送到另一个 Java 虚拟机时,它们的行为不会改变。此功能允许将新的类型和行为引入远程 Java 虚拟机,从而动态扩展应用程序的行为。此跟踪中的计算引擎示例使用此功能将新行为引入分布式程序。

远程interface,对象和方法

与其他任何 Java 应用程序一样,使用 Java RMI 构建的分布式应用程序由interface和类组成。interface声明方法。这些类实现在interface中声明的方法,也许还声明其他方法。在分布式应用程序中,某些实现可能驻留在某些 Java 虚拟机中,而不能驻留在其他虚拟机中。具有可以在 Java 虚拟机之间调用的方法的对象称为远程对象。

通过实现具有以下 Feature 的远程interface,对象将变为远程:

  • 远程interface扩展了interfacejava.rmi.Remote

  • interface的每种方法,除任何特定于应用程序的异常外,还在其throws子句中声明java.rmi.RemoteException

当对象从一个 Java 虚拟机传递到另一 Java 虚拟机时,RMI 将其与非远程对象区别对待。 RMI 不会在接收的 Java 虚拟机中复制实现对象,而是传递远程对象的远程存根。存根充当远程对象的本地代表或代理,对于 Client 端而言,它基本上是远程引用。Client 端在本地存根上调用方法,该存根负责对远程对象执行方法调用。

远程对象的存根实现与远程对象实现的相同的一组远程interface。使用此属性,可以将存根转换为远程对象实现的任何interface。但是,只有在远程interface中定义的那些方法才可以从接收 Java 虚拟机中调用。

使用 RMI 创建分布式应用程序

使用 RMI 开发分布式应用程序涉及以下一般步骤:

  • 设计和实现分布式应用程序的组件。

  • Compiling sources.

  • 使class网络可访问。

  • 启动应用程序。

设计和实现应用程序组件

首先,确定您的应用程序体系结构,包括哪些组件是本地对象以及哪些组件可以远程访问。此步骤包括:

  • 定义远程interface. 远程interface指定 Client 端可以远程调用的方法。Client 端编程为远程interface,而不是这些interface的实现类。此类interface的设计包括确定将用作这些方法的参数和返回值的对象类型。如果这些interface或类中的任何一个都不存在,则还需要定义它们。

  • 实现远程对象. 远程对象必须实现一个或多个远程interface。远程对象类可以包括仅本地可用的其他interface和方法的实现。如果要将任何本地类用作这些方法中任何一个的参数或返回值,则也必须实现它们。

  • 实现 Client 端. 可以在定义了远程interface之后(包括在部署远程对象之后)随时实现使用远程对象的 Client 端。

Compiling Sources

与任何 Java 程序一样,您可以使用javac编译器来编译源文件。源文件包含远程interface,其实现,任何其他服务器类和 Client 端类的声明。

Note:

对于 Java Platform Standard Edition 5.0 之前的版本,还需要使用rmic编译器来构建存根类,这需要执行额外的步骤。但是,此步骤不再是必需的。

使类可通过网络访问

在此步骤中,您可以通过网络访问某些类定义,例如,远程interface及其相关类型的定义以及需要下载到 Client 端或服务器的类的定义。通常通过 Web 服务器通过网络访问类定义。

启动应用程序

启动应用程序包括运行 RMI 远程对象注册表,服务器和 Client 端。

本节的其余部分将逐步介绍用于创建计算引擎的步骤。

构建通用计算引擎

本教程重点介绍一个简单但功能强大的分布式应用程序,称为计算引擎。计算引擎是服务器上的远程对象,可从 Client 端获取任务,运行任务并返回任何结果。任务在运行服务器的计算机上运行。这种类型的分布式应用程序可以使许多 Client 端计算机使用功能特别强大的计算机或具有专用硬件的计算机。

计算引擎的新颖之处在于,在编写或启动计算引擎时无需定义其运行的任务。可以随时创建新的任务,然后将其分配给要运行的计算引擎。任务的唯一要求是其类实现特定的interface。 RMI 系统可以将完成任务所需的代码下载到计算引擎。然后,计算引擎使用运行计算引擎的计算机上的资源来运行任务。

Java 平台的动态特性使执行任意任务的能力成为可能,该平台通过 RMI 扩展到网络。 RMI 将任务代码动态加载到计算引擎的 Java 虚拟机中,并且无需事先了解实现该任务的类就可以运行该任务。这种具有动态下载代码能力的应用程序通常称为基于行为的应用程序。此类应用程序通常需要完整的启用代理的基础结构。使用 RMI,此类应用程序是 Java 平台上分布式计算的基本机制的一部分。