1、什么是RMI
RMI(Remote Method Invocation)远程方法调用,RMI是从JDK1.2推出的功能,它可以实现在一个Java应用中可以像调用本地方法一样调用另一个服务器中Java应用(JVM)中的内容。
RMI 是Java语言的远程调用,无法实现跨语言。
2、执行流程
Registry(注册表)是放置所有服务器对象的命名空间。 每次服务端创建一个对象时,它都会使用bind()或rebind()方法注册该对象。 这些是使用称为绑定名称的唯一名称注册的。要调用远程对象,客户端需要该对象的引用。即通过服务端绑定的名称从注册表中获取对象(lookup()方法)。
3、API介绍
3.1 Remote
java.rmi.Remote 定义了此接口为远程调用接口。如果接口被外部调用,需要继承此接口。
3.2 RemoteException
java.rmi.RemoteException 继承了Remote接口的接口中,如果方法是允许被远程调用的,需要抛出此异常。
3.3 UnicastRemoteObject
java.rmi.server.UnicastRemoteObject 此类实现了Remote接口和Serializable接口。自定义接口实现类除了实现自定义接口还需要继承此类。
3.4 LocateRegistry
java.rmi.registry.LocateRegistry 可以通过LocateRegistry在本机上创建Registry,通过特定的端口就可以访问这个Registry。
3.5 Naming
java.rmi.Naming,Naming定义了发布内容可访问RMI名称。也是通过Naming获取到指定的远程方法。
4、代码实现
4.1 服务端创建
(1)com.example.service层
public interface DemoService extends Remote {
String demo(String param) throws RemoteException;
}
public class DemoServiceImpl extends UnicastRemoteObject implements DemoService {
public DemoServiceImpl() throws RemoteException{
}
@Override
public String demo(String param) throws RemoteException {
return param+" abc";
}
}
注意:构造方法是public的,默认生成protected。
(2)com.example层
public class DemoServer {
public static void main(String[] args) {
try {
//创建接口实例
DemoService demoService = new DemoServiceImpl();
//创建注册表
LocateRegistry.createRegistry(8989);
//绑定服务
Naming.bind("rmi://localhost:8989/demoService",demoService);
System.out.println("服务器启动成功");
} catch (RemoteException e) {
e.printStackTrace();
} catch (AlreadyBoundException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
}
(3)运行项目
运行项目后,项目一直处于启动状态,表示可以远程访问此项目中的远程方法。
4.2 创建客户端
(1)com.example.service层
public interface DemoService extends Remote {
String demo(String param) throws RemoteException;
}
(2)com.example层
public class ClientDemo {
public static void main(String[] args) {
try {
DemoService demoService = (DemoService)Naming.lookup("rmi://localhost:8989/demoService");
String result = demoService.demo("嘻嘻嘻");
System.out.println(result);
} catch (NotBoundException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (RemoteException e) {
e.printStackTrace();
}
}
}