远程方法调用
导航 并发编程 主题: ) |
Java 的远程方法调用 (通常称为 RMI) 用于客户端和服务器模型。RMI 是 RPC (远程过程调用) 的面向对象等效项。
Java 远程方法调用 (RMI) 系统允许在某个 Java 虚拟机 (VM) 中运行的对象调用在另一个 Java VM 中运行的对象的方法。RMI 提供了用 Java 编程语言编写的程序之间的远程通信。
RMI 仅定义为在 Java 平台上使用。如果需要在不同的语言环境之间调用方法,请使用 CORBA。使用 CORBA,Java 客户端可以调用 C++ 服务器,反之亦然。而 RMI 无法实现这种功能。
远程方法调用通过客户端的存根和服务器端的骨架进行。
CLIENT --> STUB --> ... Network ... --> SKELETON --> REMOTE OBJECT
在 Java 1.2 之前,必须使用 rmic 工具显式生成骨架。从 1.2 开始,使用了动态骨架,它利用 Java 反射的功能来完成工作。
远程对象可以在 RMI 注册表中列出。客户端可以通过查询注册表获取对远程对象的引用。之后,客户端可以调用远程对象上的方法。(远程对象引用也可以通过调用其他远程方法获取。注册表实际上是一个“引导程序”,解决了从哪里获取初始远程引用问题。)
RMI 注册表可以在服务器 JVM 中启动,通过 LocateRegistry.createRegistry() API 启动,或者在一个名为 rmiregistry 的单独进程中启动,该进程必须在将远程对象添加到注册表之前启动,例如在 Unix 中通过命令行启动。
Unix 上的 rmiregistry
rmiregistry <port> & |
或者在 Windows 上
Windows 上的 rmiregistry
start rmiregistry <port> |
如果没有指定 port,则使用默认端口 1099。客户端需要连接到此 port 以访问注册表。
也可以通过调用以下代码从程序中启动注册表
代码部分 1:rmiregistry 启动
import java.rmi.registry.LocateRegistry;
...
Registry reg = LocateRegistry.createRegistry(iPort);
|
作为参数传递给远程对象方法的对象将按值传递。如果远程对象更改了传入的对象值,则不会反映在客户端,这与调用本地对象时的情况相反。用作远程方法调用参数的对象必须实现 java.io.Serializable
接口,因为它们在通过网络传递时将被序列化,并且将在另一端创建一个新对象。
但是,作为参数传递的已导出的远程对象按远程引用传递。
远程对象必须扩展 java.rmi.server.UnicastRemoteObject
对象,或者通过调用 java.rmi.server.UnicastRemoteObject.exportObject()
方法显式导出。
这是一个 RMI 客户端的示例
代码清单 7.10:HelloClient.java
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class HelloClient{
private HelloClient() {}
public static void main(String[] args) {
String host = (args.length < 1) ? null : args[0];
try {
Registry registry = LocateRegistry.getRegistry(host);
Hello stub = (Hello) registry.lookup("Hello");
String response = stub.sayHello();
System.out.println("response: " + response);
} catch (Exception e) {
System.err.println("Client exception: " + e.toString());
e.printStackTrace();
}
}
}
|