JAVA RMI是什么?
Java RMI 指的是远程方法调用 (Remote Method Invocation)。它是一种机制,能够让在某个 Java 虚拟机上的对象调用另一个 Java 虚拟机中的对象上的方法。可以用此方法调用的任何对象必须实现该远程接口。
RMI是java的远端调用机制(RPC)的实现。即RMI是一组JAVA语言实现RPC的API。
通俗解释
在这个JVM中通过RMI可以调用其他JVM中对象的方法。不管是这台计算机上JVM还是其他其他计算机上的JVM。
RMI的底层是使用了TCP/IP协议进行通信的。基于JAVA中的BIO实现的。
客户端调用过程中的底层原理细节:
- 客户端通过socket发送rmi请求"rmi://127.0.0.1:1099/action"
- 客户端拿到返回的一串二进制码,这个是服务端对象的序列化。
- 客户端将二进制码反序列为对象。
- 客户端本地调用对象的方法。
- 客户端RMI底层进行通信将改变的对象更新到服务端。
服务端RMI使用方式:
- 设计远程调用的接口(如IRmiAction),该接口必须在服务端和客户端都要有。
- 定义可实例化的对象的类(如RmiActionImpl),可以直接继承UnicastRemoteObject(实现了对象序列化)
- 实现远程方法接口。
- 注册RMI端口(必需)
LocateRegistry.createRegistry(1099); - 等待接收rmi请求
Naming.rebind("rmi://127.0.0.1:1099/hello", action);
客户端RMIAPI使用方法:
- 发送请求,获得对象
IRmiAction action=(IRmiAction) Naming.lookup("rmi://127.0.0.1:1099/hello"); - 调用方法
action.add();
demo 代码
RMI远程调用方法接口
public interface IRmiAction extends Remote{
public int add() throws RemoteException;
}
对象实例以及服务端
public class RmiActionImpl extends UnicastRemoteObject implements IRmiAction{
private static final long serialVersionUID = -2241003422571775103L;
private int total=0;
protected RmiActionImpl() throws RemoteException {
super();
// TODO Auto-generated constructor stub
}
@Override
public int add() throws RemoteException {
// TODO Auto-generated method stub
total++;
return total;
}
public int getTotal(){
return total;
}
public static void main(String[] args) {
try {
LocateRegistry.createRegistry(1099);
IRmiAction action=new RmiActionImpl();
Naming.rebind("rmi://127.0.0.1:1099/hello", action);
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
客户端调用
public class RmiActionClient {
public static void main(String[] args) {
try {
IRmiAction action=(IRmiAction) Naming.lookup("rmi://127.0.0.1:1099/hello");
System.out.println(action.add());
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NotBoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}