这些Java教程是针对JDK 8编写的。本页面描述的示例和实践不利用后续版本中引入的改进,并可能使用不再可用的技术。
请参阅Java语言更改,了解Java SE 9及后续版本中更新的语言特性的概述。
请参阅JDK发行说明,了解所有JDK版本的新功能、增强功能以及已删除或弃用选项的信息。
RMI应用通常由两个独立的程序组成,一个服务器和一个客户端。一个典型的服务器程序创建一些远程对象,使得这些对象的引用可访问,并等待客户端调用这些对象的方法。一个典型的客户端程序在服务器上获取一个或多个远程对象的远程引用,然后调用它们的方法。RMI提供了服务器和客户端之间通信和传递信息的机制。这样的应用有时被称为分布式对象应用。
分布式对象应用需要执行以下操作:
下图描述了一个使用RMI注册表获取远程对象引用的RMI分布式应用。服务器调用注册表将名称与远程对象关联(或绑定)。客户端在服务器的注册表中通过名称查找远程对象,然后调用其方法。该图还显示了RMI系统使用现有的Web服务器来在需要时从服务器到客户端和从客户端到服务器加载类定义的情况。
RMI的一个核心和独特特性是它能够在接收者的Java虚拟机中下载对象类的定义,如果该类在接收者的Java虚拟机中未定义。对象的所有类型和行为,之前只能在单个Java虚拟机中使用,现在可以传输到另一个可能是远程的Java虚拟机中。RMI通过实际类传递对象,因此当它们被发送到另一个Java虚拟机时,对象的行为不会改变。这种能力使得可以向远程Java虚拟机引入新的类型和行为,从而动态扩展应用程序的行为。本教程中的计算引擎示例就利用了这个能力来为分布式程序引入新的行为。
像任何其他Java应用程序一样,使用Java RMI构建的分布式应用程序由接口和类组成。接口声明方法。类实现接口中声明的方法,并且可能还声明其他方法。在分布式应用程序中,某些实现可能存在于某些Java虚拟机中,但不存在于其他虚拟机中。可以在Java虚拟机之间调用方法的对象称为远程对象。
通过实现远程接口,对象变成远程对象,具有以下特点:
java.rmi.Remote
。throws
子句中声明java.rmi.RemoteException
,除了任何特定于应用程序的异常。RMI在将对象从一个Java虚拟机传递到另一个Java虚拟机时,与非远程对象不同地对待远程对象。RMI不会在接收方Java虚拟机中创建实现对象的副本,而是传递一个远程存根作为远程对象。存根充当本地代表或代理,对于客户端而言,它就是远程引用。客户端调用本地存根上的方法,本地存根负责在远程对象上执行方法调用。
远程对象的存根实现与远程对象实现相同的一组远程接口。这个特性使得存根可以转换为远程对象实现的任何接口。然而,只有在远程接口中定义的方法可以从接收方Java虚拟机中调用。
首先,确定应用程序架构,包括哪些组件是本地对象,哪些组件是远程可访问的。这个步骤包括:
和任何Java程序一样,你使用javac
编译器来编译源代码文件。源代码文件包含远程接口的声明,它们的实现,任何其他的服务器类和客户端类。
rmic
编译器来构建存根类。然而,这一步骤现在不再必要。
在这一步骤中,你要使某些类定义可在网络上访问,比如远程接口及其相关类型的定义,以及需要下载到客户端或服务器的类的定义。通常通过一个Web服务器来使类定义可网络访问。
启动应用程序包括运行RMI远程对象注册表、服务器和客户端。
本节的其余部分将介绍创建一个计算引擎所使用的步骤。
执行任意任务的能力是由Java平台的动态特性实现的,这个特性通过RMI扩展到网络上。RMI将任务代码动态加载到计算引擎的Java虚拟机中,并在没有先验知识的情况下运行任务的类。这种具备动态下载代码能力的应用程序通常被称为基于行为的应用程序。这类应用程序通常需要完整的代理启用基础设施。在RMI中,这类应用程序是Java平台上分布式计算的基本机制之一。