Java远程方法调用(Remote Method Invocation,RMI)

时间:2021-07-02 15:26:26

Java RMI简介:

它是Java的一个核心API和类库,允许一个Java虚拟机上运行的Java程序调用不同虚拟机上运行的对象中的方法,即使这两个虚拟机运行于物理隔离的不同主机上。

Java RMI在JDK1.1版本已经存在,是非常重要的底层技术。

下面通过一个简单的例子来测试:

 package com.tc.remote;

 import java.rmi.Remote;
import java.rmi.RemoteException; /**
* 一个远程调用接口RMIQueryStatus
* 远程接口必须声明为public
* 远程接口必须继承自java.rmi.Remote
*/
public interface RMIQueryStatus extends Remote{ // 远程调用中的方法必须抛出RemoteException异常
RMIFileStatus getFileStatus(String filename) throws RemoteException; }
 package com.tc.remote;

 import java.io.Serializable;

 /**
* RMI文件状态类,远程调用方法返回的对象
*/
public class RMIFileStatus implements Serializable{ private String filename; public RMIFileStatus() {
} public RMIFileStatus(String filename) {
this.filename = filename;
} @Override
public String toString() {
return "RMIFileStatus{" +
"filename='" + filename + '\'' +
'}';
} }
 package com.tc.remote;

 import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject; /**
* 远程接口的实现 .
*/
public class RMIQueryStatusImpl extends UnicastRemoteObject implements RMIQueryStatus { /**
* 因为UnicastRemoteObject的构造函数抛出了RemoteException异常
* 这里默认构造方法必须写
* @throws RemoteException
*/
public RMIQueryStatusImpl() throws RemoteException {
} @Override
public RMIFileStatus getFileStatus(String filename) throws RemoteException {
RMIFileStatus status = new RMIFileStatus(filename);
// ...进行处理
return status;
} }
 package com.tc.remote;

 import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry; /**
* 创建RMI注册表,启动RMI服务,并将远程对象注册到RMI注册表中。
*/
public class RMIQueryStatusServer { public static String RMI_URL = "rmi://localhost:8888/RHello"; public static void main(String[] args) {
try {
RMIQueryStatusImpl queryStatus = new RMIQueryStatusImpl();
// 注册表创建
LocateRegistry.createRegistry(8888);
// 绑定远端对象到名字
Naming.rebind(RMI_URL,queryStatus);
// Naming.bind(RMI_URL,queryStatus);
// bind方法在已经为一个名字绑定一个对象,再向此名称绑定对象,会抛出异常
// 而使用rebind方法不会
System.out.println(">>>>>INFO:远程RMIQueryStatus对象绑定成功!");
} catch (RemoteException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
}
} }
 package com.tc.remote;

 import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException; /**
* 客户端测试,在客户端调用远程对象上的远程方法,并返回结果。
*/
public class RMIQueryStatusClient { public static void main(String[] args) {
try {
RMIQueryStatus queryStatus = (RMIQueryStatus) Naming.lookup(RMIQueryStatusServer.RMI_URL);
// 调用远程方法,该调用如同调用本地方法
RMIFileStatus status = queryStatus.getFileStatus("爆炸");
System.out.println(status);
} catch (NotBoundException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (RemoteException e) {
e.printStackTrace();
}
} }

先运行RMIQueryStatusServer 的main方法:

Java远程方法调用(Remote Method Invocation,RMI)

注意:虽然main方法的执行很快,但是服务器还是会继续运行的,红色的方块表示了运行。

再运行RMIQueryStatusClient 的main方法:

Java远程方法调用(Remote Method Invocation,RMI)

这里只是简单的进行了测试,感觉Client需要拿到Server的RMI_URL,还是有比较强的依赖性。

希望实际项目中用到以后能够有更深刻的理解。

http://docs.oracle.com/javase/8/docs/technotes/guides/rmi/index.html