Java Remote Method Invocation(Java RMI) 是一个 Java API, 执行远程方法的调用,相当于 Remote Procedure Calls(RPC)。Java RMI 支持直接传输序列化的 Java 类,以及分布式的垃圾回收。
案例概况
实现一个简单的 Java RMI 可通过以下四步骤:
1. 启动 rmiregistry
2. 定义服务接口,实现服务接口,通过 rmic 工具创建存根文件( stub )
3. 实现服务端功能,并启动
4. 实现客户端功能,并调用服务端服务
具体实现
1. 启动 rmiregistry
grs:~ grs$ rmiregistry
2. 定义服务接口,实现服务接口,通过 rmic 工具创建存根文件( stub )
定义服务接口:
package service; import java.rmi.Remote;
import java.rmi.RemoteException; public interface GreetService extends Remote { String sayHello(String name) throws RemoteException; }
实现服务接口:
package service; import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject; public class GreetServiceImpl extends UnicastRemoteObject implements GreetService { static final long serialVersionUID = 1L; public GreetServiceImpl() throws RemoteException {
super();
} @Override
public String sayHello(String name) throws RemoteException {
return "Hello - " + name;
}
}
根据编译后的 GreetServiceImpl,使用 rmic 生成存根文件
grs:bin grs$ rmic service.GreetServiceImpl
执行后,目录如下
grs:bin grs$ tree
.
└── service
├── GreetService.class
├── GreetServiceImpl.class
└── GreetServiceImpl_Stub.class directories, files
grs:bin grs$
3. 实现服务端功能,并启动
package server; import java.net.MalformedURLException;
import java.rmi.AlreadyBoundException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry; import service.GreetServiceImpl; public class Server { public static void main(String[] args){ try {
LocateRegistry.createRegistry(1098);
Naming.bind("rmi://127.0.0.1:1098/GreetService", new GreetServiceImpl()); } catch (RemoteException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (AlreadyBoundException e) {
e.printStackTrace();
}
}
}
编译后,服务端文件目录结构如下:
grs:bin grs$ tree
.
├── server
│ └── Server.class
└── service
├── GreetService.class
└── GreetServiceImpl.class 2 directories, 3 files
grs:bin grs$
启动服务端
grs:bin grs$ java -server server.Server
4. 实现客户端功能,并调用服务端服务
package client; import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException; import service.GreetService; public class Client { public static void main(String[] args){ try {
String name = "rmi://127.0.0.1:1098/GreetService";
GreetService greetService = (GreetService) Naming.lookup(name); System.out.println(greetService.sayHello(" Thhhhhhh ")); } catch (MalformedURLException e) {
e.printStackTrace();
} catch (RemoteException e) {
e.printStackTrace();
} catch (NotBoundException e) {
e.printStackTrace();
}
}
}
编译后文件目录结构如下
grs:bin grs$ tree
.
├── client
│ └── Client.class
└── service
├── GreetService.class
└── GreetServiceImpl_Stub.class directories, files
grs:bin grs$
客户端调用远程端方法
grs:bin grs$ java -client client.Client
Hello - Thhhhhhh
grs:bin grs$
参考资料:
[chapter 18] Distributed Computing : remote deployment with RMI, Head First Java