Java远程调用

概述

Java远程方法调用(Remote Method Invocation, RMI)是Java的一个核心API和类库,
允许一个Java虚拟机上运行的Java程序调用不同虚拟机上运行的对象中的方法,即使这两个
虚拟机运行于物理隔离的不同主机上。在某种程度上,RMI可以看成RPC的Java升级版。

和RPC一样,存在服务端和客户端
典型服务器端应用程序 创建多个远程对象(Remote Object),使这些对象能被客户端引用,并等待客户端调用远程对象的方法
典型的客户端程序 从服务器获得一个或多个远程对象的引用,然后调用远程对象的方法


Java远程方法调用依赖于Java序列化,调用远程方法传的参数、返回值都是序列化对象


远程方法调用实例

1
2
3
4
5
6
7
8
9
/**RMIQueryStatus.java**/
import java.rmi.Remote;
import java.rmi.RemoteException;

public interface RMIQueryStatus extends Remote {

String getStatus(String name) throws RemoteException;

}

RMIQueryStatus的定义要求

  • 远程接口必须声明为public,否则客户端试着装载“实现远程接口”的远端对象时,会收到错误的消息。
  • 远程接口必须继承自java.rmi.Remote。
  • 远程接口中的每-一个方法,除了自定义的异常之外,必须将java.rmi.RemoteException
    声明于其throws子句中。
  • 在远程方法声明中,作为参数或者返回值的远程对象,或者包含在其他非远程对象中
    的远程对象,必须声明为其对应的远程接口,而不是实际的实现类。(这点在String类中并没有体现)

RMIQueryStatus的实现类

1
2
3
4
5
6
7
8
9
10
11
12
/**RMIQueryStatusImp.java**/
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

public class RMIQueryStatusImp extends UnicastRemoteObject implements RMIQueryStatus {
protected RMIQueryStatusImp() throws RemoteException {
}

public String getStatus(String name) throws RemoteException {
return "I'm " + name + ".";
}
}

客户端和服务端的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
/**RMIDemoServer**/
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;

/**
* @author lyhcc
*/

public class RMIDemoServer {
public static void main(String[] args) throws RemoteException, MalformedURLException {
//1. 创建RMIQueryStatus对象
RMIQueryStatusImp queryService = new RMIQueryStatusImp();

//2. 设置服务端口
LocateRegistry.createRegistry(12090);

//3. 绑定远端对象名
Naming.rebind("rmi://localhost:12090/queryTest", queryService);
System.out.println("Server is running!");
}
}

/**客户端的代码**/


import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;

public class RMIDemoClient {
public static void main(String[] args) throws RemoteException, NotBoundException, MalformedURLException {
//1. 创建RMIQueryStatusImp对象
RMIQueryStatus queryStatus = (RMIQueryStatus) Naming.lookup("rmi://localhost:12090/queryTest");

//2. 调用远程方法
String status = queryStatus.getStatus("KiKi");

System.out.println(status);
}
}

先运行服务端然后运行客户端查看结果

Java远程调用实例类图


客户端RMIQueryStatusClient的工作依赖于RMI存根(Stub),这个存根是通过Java的代理机制 java.lang.reflect.Proxy


Comments

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×