Java RMI通过定义继承Remote的接口(如MyService)、实现类(如MyServiceImpl)、启动rmiregistry并绑定服务(Naming.rebind)、客户端查找存根(Naming.lookup)并调用方法,实现远程对象调用。整个过程由RMI自动处理序列化、网络传输和方法转发,使远程调用如同本地调用一样透明。

Java RMI(Remote Method Invocation)允许一个Java虚拟机上的对象调用另一个Java虚拟机上的对象方法,实现远程过程调用。它的核心是让远程调用看起来像本地调用一样,屏蔽网络通信的复杂性。
1. 定义远程接口
远程对象的方法必须通过一个继承java.rmi.Remote的接口来声明。接口中的每个方法都必须声明抛出RemoteException,表示可能因网络问题失败。
- 接口定义服务提供哪些可被远程调用的方法。 - 例如:public interface MyService extends Remote {
String sayHello() throws RemoteException;
}2. 实现远程接口
创建一个类实现上面定义的远程接口,并提供具体逻辑。这个类的实例将作为远程对象被客户端调用。
- 实现类通常继承UnicastRemoteObject,以便自动支持远程通信。 - 构造函数会抛出RemoteException,因为需要导出对象到RMI运行时。 - 示例:public class MyServiceImpl extends UnicastRemoteObject implements MyService {
protected MyServiceImpl() throws RemoteException { super(); }
public String sayHello() throws RemoteException { return "Hello from server"; }
}3. 启动RMI注册表并绑定服务
RMI注册表(rmiregistry)是一个命名服务,用来注册远程对象并供客户端查找。
立即学习“Java免费学习笔记(深入)”;
- 可以通过命令行启动:`rmiregistry 1099`(默认端口1099)。 - 在服务端代码中,使用Naming.rebind()或Registry.bind()把远程对象绑定到一个名称上。 - 例如:MyService service = new MyServiceImpl();
Naming.rebind("rmi://localhost/MyService", service);
4. 客户端查找并调用远程方法
客户端通过RMI注册表查找远程对象的引用,然后像调用本地对象一样调用其方法。
- 使用Naming.lookup()根据URL获取远程对象的存根(stub)。 - 存根是远程对象的代理,负责将方法调用封装成网络请求发送给服务端。 - 示例:MyService stub = (MyService) Naming.lookup("rmi://localhost/MyService");
String result = stub.sayHello(); // 实际发生远程调用整个过程中,RMI自动处理了序列化、网络传输、方法转发和结果返回。客户端持有的是stub,服务端有skeleton(在新版本中已隐式处理),两者完成跨JVM通信。
基本上就这些。只要接口规范、网络通畅、类路径正确,RMI就能透明地完成远程调用。











