1.RMI简介
RMI(Remote Method Invocation)即远程方法调用。 RMI的概念非常类似于windows操作系统中的RPC。它可以允许一个java虚拟机中的程序远程的调用另一个java虚拟机中的程序,具体执行的代码是在被调用程序所在的机器中执行的。
2.编写一个RMI服务端
编写一个RMI服务端需要完成以下三个部分的内容。
- 1.一个继承了
java.rmi.Remote
的接口
//IRemoteHello.java import java.rmi.Remote; import java.rmi.RemoteException; public interface IRemoteHello extends Remote { public String hello() throws RemoteException; }
- 2.一个继承了
java.rmi.server.UnicastRemoteObject
并实现了上述接口的类
//RemoteHello.java import java.rmi.RemoteException; import java.rmi.server.UnicastRemoteObject; public class RemoteHello extends UnicastRemoteObject implements IRemoteHello { protected RemoteHello() throws RemoteException{ } public String hello() throws RemoteException { System.out.println("GET A RMI CALL!"); return "Hello"; } }
- 3.一个创建Registry,实例化上述类并绑定的主类。
//RMIServer.java import java.net.MalformedURLException; import java.rmi.AlreadyBoundException; import java.rmi.Naming; import java.rmi.RemoteException; import java.rmi.registry.LocateRegistry; public class RMIServer { public static void main(String[] args) throws Exception { RemoteHello h = new RemoteHello(); LocateRegistry.createRegistry(1099); Naming.bind("rmi://127.0.0.1:1099/hello",h); } }
上述代码,当运行RMIServer.java
的main
方法时java程序将会监听1099端口,等待客户端连接。
3.编写一个RMI客户端
客户端只需要知道远程服务端实现的接口和绑定的rmi地址即可远程调用。因此客户端需要的文件如下:
- 1.和服务端那边一样的接口文件
//IRemoteHello.java import java.rmi.Remote; import java.rmi.RemoteException; public interface IRemoteHello extends Remote { public String hello() throws RemoteException; }
- 2.调用远程方法的主类
import java.net.MalformedURLException; import java.rmi.Naming; import java.rmi.NotBoundException; import java.rmi.RemoteException; public class RMIClient { public static void main(String[] args) throws RemoteException, MalformedURLException, NotBoundException { IRemoteHello hello = (IRemoteHello) Naming.lookup("rmi://192.168.1.103:1099/hello"); String ret = hello.hello(); System.out.println(ret); } }
可以看到,客户端并不需要知道实现了IRemoteHello接口类的具体代码,唯一需要做的事情就是调用该接口里面的方法。上述代码运行后,即可远程调用该IRemoteHello接口中的hello方法,如下图:
客户端得到返回结果hello
服务端输出指定内容,说明具体代码确实是在服务端执行的