RMI (Remote Method Invocation) 远程方法调用,可以认为是RPC的Java版本,使用 RMI 技术可以使一个Java 虚拟机中的对象,调用另一个Java 虚拟机中的对象方法并获取调用结果。
使用的是JRMP(Java Remote Messaging Protocol)协议,JRMP是专门为Java定制的通信协议,所以是纯Java的分布式解决方案,对用非Java语言开发的应用系统的支持不足,不能与用非Java语言书写的对象进行通信。
RMI 在编写一个接口需要作为远程调用时,都需要继承了Remote,Remote 接口用于标识其方法可以从非本地虚拟机上调用的接口,只有在“远程接口”(扩展java.rmi.Remote的接口)中指定的这些方法才可远程使用。
那么我们要如何来使用RMI,其主要的使用步骤如下:
- 创建一个远程接口,并继承 java.rmi.Remote 接口
- 实现远程接口,并且继承 UnicastRemoteObject
- 创建服务器程序,同时使用 createRegistry 方法注册远程接口对象
- 创建客户端程序,通过 Naming 类的 lookup 方法来远程调用接口中的方法
1、创建一个远程接口,并继承 java.rmi.Remote 接口
package com.rockvine.rmi.server;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface RmiDemoService extends Remote {
String sayHello(String name) throws RemoteException;
}
该接口必须继承Remote接口,并且所有方法需要抛出RemoteException异常,另外所有参数和返回类型必须序列化(要进行网络传输)。
2、实现远程接口,并且继承 UnicastRemoteObject
package com.rockvine.rmi.server;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
public class RmiDemoServiceImpl extends UnicastRemoteObject implements RmiDemoService{
protected RmiDemoServiceImpl() throws RemoteException {
super();
}
@Override
public String sayHello(String name) throws RemoteException {
return "Hello, " + name;
}
}
必须继承UnicastRemoteObject,以允许JVM创建远程的存根/代理
3、创建服务器程序,同时使用 createRegistry 方法注册远程接口对象
package com.rockvine.rmi.server;
import java.rmi.Naming;
import java.rmi.registry.LocateRegistry;
public class Server {
public static void main(String[] args) {
try {
// 接口实例化
RmiDemoService rmiDemoService = new RmiDemoServiceImpl();
// 将服务注册到8888端口
LocateRegistry.createRegistry(8888);
// 把接口实例绑定到端口的一个路径上
Naming.bind("rmi://127.0.0.1:8888/rmi-demo", rmiDemoService);
} catch (Exception e) {
System.out.println("注册远程对象失败,错误信息:" + e.getMessage());
}
}
}
4、创建客户端程序,通过 Naming 类的 lookup 方法来远程调用接口中的方法
package com.rockvine.rmi.client;
import java.rmi.Naming;
public class Client {
public static void main(String[] args) {
try {
// 通过RMI发现服务并且转成一个对象
RmiDemoService demoService = (RmiDemoService) Naming.lookup("rmi://127.0.0.1:8888/rmi-demo");
// 远程调用下服务方法
System.out.println(demoService.sayHello("RMI"));
} catch (Exception e) {
System.out.println("调用远程对象失败,错误信息:" + e.getMessage());
}
}
}
最后进行测试,先启动服务端Server,然后再启动客户端Client即可,结果如下:



