分享
 
 
 

RMI规范(2)

王朝java/jsp·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

RMI规范--第二章

Java 分布式对象模型

2.1 分布式对象应用程序

RMI 应用程序通常包括两个独立的程序:服务器程序和客户机程序。典型的服务

器应用程序将创建多个远程对象,使这些远程对象能够被引用,然后等待客户机

调用那些远程对象上的方法。而典型的客户机程序则从服务器中得到一个或多个

远程对象的引用,然后调用远程对象的方法。RMI 为服务器和客户机进行通讯

和信息传递提供了一种机制。这样的应用程序有时被称为分布式对象应用程序。

分布式对象应用程序需要:

定位远程对象

应用程序可使用两种机制中的一种得到对远程对象的引用。它既可用 RMI 的简

单命名工具 rmiregistry 来注册它的远程对象;也可将远程对象引用作为常规

操作的一部分来进行传递和返回。

与远程对象通讯

远程对象间通讯的细节由 RMI 处理;对于程序员来说,远程通讯看起来就象标

准的 Java 方法调用。给作为参数或返回值传递的对象加载类字节码因为 RMI

允许调用程序将纯 Java 对象传给远程对象,所以 RMI 将提供必要的机制,

既可以加载对象的代码又可以传输对象的数据。

服务器调用注册服务程序以使名字与远程对象相关联。客户机在服务器注册服务

程序中用远程对象的名字查找该远程对象,然后调用它的方法。RMI 能用 Java

系统支持的任何 URL 协议(例如 HTTP、FTP、file 等)加载类字节码。

2.2 术语的定义

在 Java 分布式对象模型中,remote object 是这样一种对象:它的方法可以

从其它 Java 虚拟机(可能在不同的主机上)中调用。该类型的对象由一种或

多种 remote interfaces(它是声明远程对象方法的 Java 接口)描述。

远程方法调用 (RMI) 就是调用远程对象上远程接口的方法的动作。更为重要的

是,远程对象的方法调用与本地对象的方法调用语法相同。

2.3 分布式和非分布式模型的比较

Java 分布式对象模型在以下几方面与 Java 对象模型相似:

远程对象的引用在任一种方法调用中(本地或远程)都能以参数形式传递或以结

果形式返回。

远程对象可以被强制转换成任何远程界面,只要该界面为使用内置 Java 语法

进行强制类型转换的实现所支持。

内置 Java 操作符 instanceof 可用来测试远程对象所支持的远程接口。

Java 分布式对象模型在以下几方面与 Java 对象模型不同:

远程对象的客户机与远程接口发生交互,而从不与这些接口的实现类交互。

远程方法的非远程参数和返回结果是通过复制而非引用的方式传递的。这是因为

对象的引用只在单个虚拟机中才有用。

远程对象以引用的方式进行传递,而不是复制实际的远程实现。

某些 java.lang.Object 类定义的方法的语义专用于远程对象。

因为调用远程对象的失败模式本来就比调用本地对象的失败模式复杂,所以客户

机必须处理远程方法调用期间发生的额外异常。

2.4 RMI 接口和类概述

2.4.1 java.rmi.Remote 接口

在 RMI 中,远程接口是声明了可从远程 Java 虚拟机中调用的方法集。远程接

口必须满足下列要求:

远程接口至少必须直接或间接扩展 java.rmi.Remote 接口。

远程接口中的方法声明必须满足下列远程方法声明的要求:

远程方法声明在其 throws 子句中除了要包含与应用程序有关的异常(注意与

应用程序有关的异常无需扩展 java.rmi.RemoteException )之外,还必须包

括 java.rmi.RemoteException 异常(或它的超类,例如

java.io.IOException 或 java.lang.Exception )。

远程方法声明中,作为参数或返回值声明的(在参数表中直接声明或嵌入到参数

的非远程对象中)远程对象必须声明为远程接口,而非该接口的实现类。

java.rmi.Remote 接口是一个不定义方法的标记接口:

public interface Remote

远程接口必须至少扩展 java.rmi.Remote 接口(或其它扩展

java.rmi.Remote 的远程接口)。然而,远程接口在下列情况中可以扩展非远

程接口:

远程接口也可扩展其它非远程接口,只要被扩展接口的所有方法(如果有)满足

远程方法声明的要求。

例如,下面的接口 BankAccount 即为访问银行帐户定义了一个远程接口。它包

含往帐户存款、使帐户收支平衡和从帐户取款的远程方法:

public interface BankAccount extends java.rmi.Remote

{

public void deposit(float amount)

throws java.rmi.RemoteException;

public void withdraw(float amount)

throws OverdrawnException, java.rmi.RemoteException;

public float getBalance()

throws java.rmi.RemoteException;

}

下例说明了有效的远程接口 Beta。它扩展非远程接口 Alpha(有远程方法)和

接口 java.rmi.Remote:

public interface Alpha

{

public final String okay = "constants are okay too";

public Object foo(Object obj)

throws java.rmi.RemoteException;

public void bar() throws java.io.IOException;

public int baz() throws java.lang.Exception;

}

public interface Beta extends Alpha, java.rmi.Remote {

public void ping() throws java.rmi.RemoteException;

}

2.4.2 RemoteException 类

java.rmi.RemoteException 类是在远程方法调用期间由 RMI 运行时所抛出

的异常的超类。为确保使用 RMI 系统的应用程序的健壮性,远程接口中声明的

远程方法在其 throws 子句中必须指定 java.rmi.RemoteException(或它的

超类,例如 java.io.IOException 或 java.lang.Exception)。

当远程方法调用由于某种原因失败时,将抛出 java.rmi.RemoteException 异

常。远程方法调用失败的原因包括:

通讯失败(远程服务器不可达或拒绝连接;连接被服务器关闭等。)

参数或返回值传输或读取时失败

协议错误

RemoteException 类是一个已检验的异常(必须由远程方法的调用程序处理并

经编译器检验的异常),而不是 RuntimeException。

2.4.3 RemoteObject 类及其子类

RMI 服务器函数由 java.rmi.server.RemoteObject 及其子类

java.rmi.server.RemoteServer、java.rmi.server.UnicastRemoteObject

和 java.rmi.activation.Activatable 提供。

java.rmi.server.RemoteObject 为对远程对象敏感的 java.lang.Object

方法、hashCode、 equals 和 toString 提供实现。

创建远程对象并将其导出(使它们可为远程客户机利用)所需的方法由类

UnicastRemoteObject 和 Activatable 提供。子类可以识别远程引用的语义,

例如服务器是简单的远程对象还是可激活的远程对象(调用时将执行的远程对象)。

java.rmi.server.UnicastRemoteObject 类定义了单体(单路传送)远程对

象,其引用只有在服务器进程活着时才有效。

类 java.rmi.activation.Activatable 是抽象类,它定义的 activatable

远程对象在其远程方法被调用时开始执行并在必要时自己关闭。

2.5 实现远程接口

实现远程接口的类的一般规则如下:

该类通常扩展 java.rmi.server.UnicastRemoteObject,因而将继承类

java.rmi.server.RemoteObject 和java.rmi.server.RemoteServer 提供

的远程行为。

该类能实现任意多的远程接口。

该类能扩展其它远程实现类。

该类能定义远程接口中不出现的方法,但这些方法只能在本地使用而不能在远程

使用。

例如,下面的类 BankAcctImpl 实现 BankAccount 远程接口并扩展

java.rmi.server.UnicastRemoteObject 类:

package mypackage;

import java.rmi.RemoteException;

import java.rmi.server.UnicastRemoteObject;

public class BankAccountImpl extends UnicastRemoteObject implements

BankAccount

{

private float balance = 0.0;

public BankAccountImpl(float initialBalance)

throws RemoteException

{

balance = initialBalance;

}

public void deposit(float amount) throws RemoteException

{

...

}

public void withdraw(float amount) throws OverdrawnException,

RemoteException

{

...

}

public float getBalance() throws RemoteException

{

...

}

}

注意:必要时,实现远程接口的类能扩展除

java.rmi.server.UnicastRemoteObject 类以外的其它一些类。但实现类此

时必须承担起一定的责任,即导出对象(由 UnicastRemoteObject 构造函数

负责)和实现从 java.lang.Object 类继承的 hashCode、 equals 和

toString 方法的正确远程语义(如果需要)。

2.6 远程方法调用中的参数传递

传给远程对象的参数或源于它的返回值可以是任意可序列化的 Java 对象。这包

括 Java 基本类型, 远程?Java 对象和实现 java.io.Serializable 接口的

非远程 Java 对象。有关如何使类序列化的详细信息,参见 Java“对象序列化

规范”。本地得不到的作为参数或返回值的类,可通过 RMI 系统进行动态下载。

有关 RMI 读取参数、返回值和异常时如何下载参数和返回值类的详细信息,参

见“动态类加载”(3.4)一节。

2.6.1 传递非远程对象

非远程对象将作为远程方法调用的参数传递或作为远程方法调用的结果返回时,

是通过复制传递的;也就是使用 Java 对象序列化机制将该对象序列化。

因此,在远程对象调用过程中,当非远程对象作为参数或返回值传递时,非远程

对象的内容在调用远程对象之前将被复制。

从远程方法调用返回非远程对象时,将在调用的虚拟机中创建新对象。

2.6.2 传递远程对象

当将远程对象作为远程方法调用的参数或返回值传递时,远程对象的 stub 程序

即被传递出去。作为参数传递的远程对象仅能实现远程接口。

2.6.3 引用的完整性

如果一个对象的两个引用在单个远程方法调用中以参数形式(或返回值形式)从

一个虚拟机传到另一个虚拟机中,并且它们在发送虚拟机中指向同一对象,则两

个引用在接收虚拟机中将指向该对象的同一副本。进一步说就是:在单个远程方

法调用中,RMI 系统将在作为调用参数或返回值传递的对象中保持引用的完整性

2.6.4 类注解

当对象在远程调用中被从一个虚拟机发送到另一个虚拟机中时,RMI 系统在调用

流中用类的信息 (URL) 给类描述符加注解,以便该类能在接收器上加载。在远

程方法调用期间,调用可随时下载类。

2.6.5 参数传输

为将 RMI 调用的参数序列化到远程调用的目的文件里,需要将该参数写入作为

java.io.ObjectOutputStream 类的子类的流中。ObjectOutputStream 子类

将覆盖 replaceObject 方法,目的是用其相应的 stub 类取代每个远程对象。

对象参数将通过 ObjectOutputStream 的 writeObject 方法写入流中。而

ObjectOutputStream 则通过 writeObject 方法为每个写入流中的对象(包

含所写对象所引用的对象)调用 replaceObject 方法。RMIObjectOutputStream

子类的 replaceObject 方法返回下列值:

如果传给 replaceObject 的对象是 java.rmi.Remote 的实例,则返回远程对

象的 stub 程序。远程对象的 stub 程序通过对

java.rmi.server.RemoteObject.toStub

方法的调用而获得。

如果传给 replaceObject 的对象不是 java.rmi.Remote 的实例,则只返回

该对象。

RMI 的 ObjectOutputStream 子类也实现 annotateClass 方法,该方法用类

的位置注解调用流以便能在接收器中下载该类。有关如何使用 annotateClass

的详细信息,参见“动态类加载”一节。

因为参数只写入一个 ObjectOutputStream,所以指向调用程序同一对象的引用

将在接收器那里指向该对象的同一副本。在接收器上,参数将被单个

ObjectInputStream 所读取。

用于写对象的 ObjectOutputStream(类似的还有用于读对象的

ObjectInputStream )的所有其它缺省行为将保留在参数传递中。例如,写对

象时对 writeReplace 的调用及读对象时对 readResolve 的调用就是由 RMI

的参数编组与解编流完成的。

与上述 RMI 参数传递方式类似,返回值(或异常)将被写入

ObjectOutputStream

的子类并和参数传输的替代行为相同。

2.7 定位远程对象

我们专门提供了一种简单的引导名字服务器,用于存储对远程对象的已命名引用

。使用类 java.rmi.Naming 的基于 URL 的方法可以存储远程对象引用。

客户机要调用远程对象的方法,则必须首先得到该对象的引用。对远程对象的引

用通常是在方法调用中以返回值的形式取得。RMI 系统提供一种简单的引导名字

服务器,通过它得到给定主机上的远程对象。java.rmi.Naming 类提供基于统

一资源定位符 (URL) 的方法,用来绑定、再绑定、解开和列出位于某一主机及

端口上的名字-对象对。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有