简介
Java RMI (Remote Method Invocation) 远程方法调用,能够让客户端像使用本地调用一样调用服务端 Java 虚拟机中的对象方法。RMI 是面向对象语言领域对 RPC (Remote Procedure Call)的完善,用户无需依靠 IDL (接口描述语言)的帮助来完成分布式调用, 而是用这种更简单的依赖接口方式。
RMI的优势
这种机制给分布式计算的系统及编程都带来了极大的方便。按照RMI规则设计程序,可以不必再关心网络细节,如TCP和Socket等等。任意2台计算机之间的通讯完全由RMI负责。
-
面向对象 : RMI可将完整的对象作为参数和返回值进行传递,而不仅仅是预定义的数据类型
-
可移动属性 : RMI可将属性(类实现程序)从客户机移动到服务器,反义亦可。
-
设计方式 : 对象传递功能使你可以在分布式计算中充分利用面向对象技术的强大功能,如二层和三层结构系统。如果用户能够传递属性,那么就可以在自己的解决方案中使用面向对象的设计方式。所有面向对象的设计方式无不依靠不同的属性来发挥功能,如果不能传递完整的对象——包括实现和类型——就会失去设计方式上所提供的优点。
-
安全性 : RMI使用Java内置的安全机制保证下载执行程序时用户系统的安全。RMI使用专门为保护系统免遭恶意小程序侵害而设计的安全管理程序。
-
便于开发使用 : 远程接口就是Java接口
-
多线程 :RMI采用多线程处理方式,更好处理客户端请求
-
优势基本都是基于其语言本身
工作原理
-
服务端向 RMI 注册服务绑定自己的地址;
-
客户端通过 RMI 注册服务获取目标地址;
-
客户端调用本地的 Stub 对象上的方法,和调用本地对象上的方法一致;
-
本地存根对象将调用信息打包,通过网络发送到服务端;
-
服务端的 Skeleton 对象收到网络请求之后,将调用信息解包;
-
然后找到真正的服务对象发起调用,并将返回结果打包通过网络发送回客户端。
示例代码
1、远程接口
public interface RemoteServer extends Remote {
String print2() throws RemoteException;
}
2、远程接口实现
public class RemoteServerImpl extends UnicastRemoteObject implements RemoteServer{
private static final long serialVersionUID = -5697597527130126131L;
private String information;
protected RemoteServerImpl(String info) throws RemoteException {
information = info;
}
@Override
public String print2() throws RemoteException {
System.err.println("RemoteServerImpl--print2");
return information;
}
}
3、服务端
public class PrintServer {
public static void main(String[] args) {
try {
// 启动RMI注册服务,1099默认端口
LocateRegistry.createRegistry(1099);
// 创建远程对象
RemoteServer remoteServer = new RemoteServerImpl("Hello, Java.");
// 把远程对象注册到RMI注册服务器上
Naming.bind("printServer", remoteServer);
System.err.println("printServer is OK");
} catch (Exception e) {
System.err.println("printServer is exception");
e.printStackTrace();
}
}
}
4、客户端
public class PrintClient {
public static void main(String[] args) {
try {
RemoteServer remoteServer = (RemoteServer) Naming.lookup("printServer");
System.err.println(remoteServer.print2());
} catch (Exception e) {
e.printStackTrace();
}
}
}
RMI 和 socket 比较
- RMI是面向对象的,socket不是
- RMI是Java语言特定的一种机制,而socket网络编程是独立于开发语言的
- 网络协议,socket是在TCP上,而RMI是在TCP上,再次定义了自己的协议(Java远程方法协议--JRMP)
- 性能,socket性能优于RMI,尤其是在传输大量数据时