⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rmi

📁 一个rmi例子程序
💻
📖 第 1 页 / 共 3 页
字号:
RMI规范--第五章 

服务器接口 
java.rmi.server 包包含通常用于实现远程对象的接口与类。 

主题: 
RemoteObject 类 
RemoteServer 类 
UnicastRemoteObject 类 
Unreferenced 接口 
RMISecurityManager 类 
RMIClassLoader 类 
LoaderHandler 接口 
RMI 套接字工厂 
RMIFailureHandler 接口 
LogStream 类 
stub 和 skeleton 编译器 

5.1 RemoteObject 类 
类 java.rmi.server.RemoteObject 将 java.lang.Object 行为实现于远程 
对象。实现方法 hashCode 和 equals 将允许将远程对象引用存储在散列表中 
进行比较。如果两个 Remote 对象引用同一个远程对象,则方法 equals 的返 
回值为 true。它负责比较远程对象的远程对象引用。 

方法 toString 返回一个说明远程对象的字符串。该字符串的内容和语法与实 
现有关且可变。 

java.lang.Object 中的其它方法保留了它们的原始实现。 

package java.rmi.server; 
public abstract class RemoteObject 
implements java.rmi.Remote, java.io.Serializable 
{ 
protected transient RemoteRef ref; 
protected RemoteObject(); 
protected RemoteObject(RemoteRef ref); 
public RemoteRef getRef(); 
public static Remote toStub(java.rmi.Remote obj) 
throws java.rmi.NoSuchObjectException; 
public int hashCode(); 
public boolean equals(Object obj); 
public String toString(); 
} 

因为 RemoteObject 是抽象类,所以无法实例化。因此,RemoteObject 的构 
造函数必须从子类实现中调用。第一个 RemoteObject 构造函数将创建带空的 
远程引用的 RemoteObject。第二个 RemoteObject 构造函数将创建带给定远 
程引用 ref 的 RemoteObject。 

方法 getRef 返回该远程对象的远程引用。 

方法 toStub 返回一个远程对象 obj 的 stub 并作为参数传送。该操作仅在 
已经导出远程对象实现后才有效。如果找不到远程对象的 stub,该方法就抛出 
NoSuchObjectException。 

5.1.1 RemoteObject 类覆盖的对象方法 
java.lang.Object 类中用于方法 equals、hashCode 和 toString 的缺省实 
现不适用于远程对象。因此,RemoteObject 类提供了这些方法在语义上更合适 
于远程对象的实现。 

equals 和 hashCode 方法 
为将远程对象用作散列表中的主键,我们必须在远程对象实现中覆盖 equals 和 
hashCode 方法,这些方法是由类 java.rmi.server.RemoteObject 覆盖的: 

java.rmi.server.RemoteObject 类实现 equals 方法决定了两个对象的引用 
是否相等,而不是两个对象的内容是否相等。这是因为决定内容是否相等时需要 

远程方法调用,而 equals 的签名不允许抛出远程异常。 
对于所有引用同一底层远程对象的远程引用,java.rmi.server.RemoteObject 
类实现的 hashCode 方法返回同一个值(因为对相同对象的引用被认为是相等 

的)。 

toString 方法 
toString 方法被定义为返回表示对象的远程引用的字符串。字符串的内容视引 
用的类型而定。单体(单路传送)对象的当前实现一个对象标识符以及与传输层 
有关的该对象的其他信息(例如主机名和端口号)。 

clone 方法 
只有在对象支持 java.lang.Cloneable 接口时才能用 Java 语言的缺省机制 
来复制。由 rmic 编译器生成的远程对象的 stub 将被声明为终态,且不实现 
Cloneable 接口,因此无法复制 stub。 

5.1.2 序列化形式 
RemoteObject 类实现专门的(私用)方法 writeObject 和方法 readObject, 
它们由对象序列化机制调用来处理向 java.io.ObjectOutputStream 中序列化 
数据。RemoteObject 的序列化形式由下列方法写入: 
private void writeObject(java.io.ObjectOutputStream out) 
throws java.io.IOException, java.lang.ClassNotFoundException; 
如果 RemoteObject 的远程引用域 ref 为空,则该方法抛出 
java.rmi.MarshalException。 
如果远程引用 ref 为非空: 
ref 的类通过调用其 getRefClass 方法来获得,该方法通常返回远程引用类的 
非打包全名。如果返回的类名为非空: 
ref 的类名将以 UTF 格式写到流 out 中。 

调用 ref 的方法 writeExternal,传递的参数为流 out,从而使 ref 可以将 
其外部表示法写到流中。 

如果 ref.getRefClass 返回的类名为空: 
则将一个 UTF 格式的空字符串写到流 out 中。 

ref 被序列化到流 out(即利用 writeObject)。 
序列化恢复时,RemoteObject 的状态将由 ObjectInputStream 调用该方法利 
用其序列化形式进行重构: 

private void readObject(java.io.ObjectInputStream in) 
throws java.io.IOException, java.lang.ClassNotFoundException; 

首先,ref 的类名(UTF 字符串)将从流 in 中读出。如果类名为空字符串: 
则从流中读出对象,然后将 ref 初始化为该对象(即通过调用 in.readObject) 
如果类名为非空: 
则 ref 的完整类名由字符串 java.rmi.server.RemoteRef.packagePrefix 的 
值和“.”加上从流中读取的类名相连接而成。 
创建 ref 类的实例(利用上述完整类名)。 
该新实例(成为 ref 域)从流 in 中读取其外部形式。 

2 RemoteServer 类 
java.rmi.server.RemoteServer 类是服务器实现类 
java.rmi.server.UnicastRemoteObject 
和 java.rmi.activation.Activatable 的通用超类。 

package java.rmi.server; 
public abstract class RemoteServer extends RemoteObject 
{ 

protected RemoteServer(); 
protected RemoteServer(RemoteRef ref); 

public static String getClientHost() 
throws ServerNotActiveException; 
public static void setLog(java.io.OutputStream out); 
public static java.io.PrintStream getLog(); 
} 


因为 RemoteServer 是抽象类,所以将无法实例化。因此,必须从子类实现中 
调用某一 RemoteServer 的构造函数。第一个 RemoteServer 构造函数将创建 
带空远程引用的 RemoteServer。第二个 RemoteServer 构造函数将创建带给 
定远程引用 ref 的 RemoteServer。 

getClientHost 方法允许一个活动方法确定当前线程中活动的远程方法是由哪 
台主机初始化的。如果当前线程中没有活动的远程方法,则抛出异常 ServerNot 
ActiveException。 
setLog 方法将 RMI 调用记录到指定输出流中。如果输出流为空,则关闭调用 
日志。getLog 方法返回 RMI 调用日志流,从而使特定于应用程序的信息以同 
步方式写到调用日志中。 

5.3 UnicastRemoteObject 类 
类 java.rmi.server.UnicastRemoteObject 支持创建并导出远程对象。该类 
实现的远程服务器对象具有下列特征: 

对这种对象的引用至多仅在创建该远程对象的进程生命期内有效。 
通过 TCP 传输与远程对象通信。 
调用、参数和结果使用流协议在客户机和服务器之间进行通信。 
package java.rmi.server; 
public class UnicastRemoteObject extends RemoteServer 
{ 

protected UnicastRemoteObject() 
throws java.rmi.RemoteException; 
protected UnicastRemoteObject(int port) 
throws java.rmi.RemoteException; 
protected UnicastRemoteObject(int port, 
RMIClientSocketFactory csf, 
RMIServerSocketFactory ssf) 
throws java.rmi.RemoteException; 
public Object clone() 
throws java.lang.CloneNotSupportedException; 
public static RemoteStub exportObject(java.rmi.Remote obj) 
throws java.rmi.RemoteException; 
public static Remote exportObject(java.rmi.Remote obj, int port) 
throws java.rmi.RemoteException; 
public static Remote exportObject(Remote obj, int port, 
RMIClientSocketFactory csf, 
RMIServerSocketFactory ssf) 
throws java.rmi.RemoteException; 
public static boolean unexportObject(java.rmi.Remote obj, boolean force) 
throws java.rmi.NoSuchObjectException; 
} 

  
5.3.1 构造新远程对象 
远程对象实现(实现一个或多个远程接口的实现)必须被创建和导出。导出远程 
对象使得对象能接受来自客户机的到来的调用。作为 UnicastRemoteObject 
导出的远程对象,其导出涉及在 TCP 端口监听(注意,多个远程对象可以接受 
同一端口的到来的调用,因此没必要在新的端口上监听)。远程对象实现可以扩 
展类 UnicastRemoteObject 以使用其导出对象的构造函数,或者扩展其它类 
(或者根本不扩展)并通过 UnicastRemoteObject 的 exportObject 方法导 
出对象。 

无参数的构造函数将创建远程对象并在匿名(或任意)端口上导出,而这将在运 
行时进行选择。第二种形式的构造函数带单个参数(即 port),它指定远程对 
象接受到来的调用的端口号。第三种构造函数创建的远程对象在指定端口上通过 
RMIServerSocketFactory 创建的 ServerSocket 接受到来的调用;客户机 
通过由 RMIClientSocketFactory 提供的 Socket 与远程对象建立连接。 

5.3.2 导出并非由 RemoteObject 扩展而来的实现 
exportObject 方法(任何形式)可用于导出不是由扩展 UnicastRemoteObject 
类实现的简单对等远程对象。第一种形式的 exportObject 方法带单个参数 
(即 obj),它是接受到来的 RMI 调用的远程对象;该 exportObject 方法 
在匿名(或任意)端口上导出远程对象,而这将在运行时进行选择。第二种形式 
的 exportObject 方法带两个参数,分别是远程对象 obj 和 port。port 是 
远程对象接受到来的调用的端口号。第三种 exportObject 方法用指定的 
RMIClientSocketFactory、csf 和 RMIServerSocketFactory、ssf 在指定 
port 上导出对象 obj。 
在作为参数或返回值传入 RMI 调用前,必须导出对象,否则当试图把“未导出 
的”对象作为参数或返回值传递给一个远程调用时,将会抛出 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -