JAVA RMI入门
1、定义
Java远程方法调用,即Java RMI (Java Remote Method Invocation),是Java编程语言里,一种用于实现远程过程调用的应用程序编程接口。它使客户机上运行的程序可以直接调用远程服务器上的对象。远程方法调用特性使Java编程人员能够在网络环境中分布操作。
RMI(Remote Method Invocation)为远程方法调用,是允许运行在一个Java虚拟机的对象调用运行在另一个Java虚拟机上的对象的方法。这两个虚拟机可以是运行在相同计算机上的不同进程中,也可以是运行在网络上的不同计算机中。
RMI的基础是接口,RMI构架基于一个重要的原理:定义接口和定义接口的具体实现是分开的。
2、原理
服务端:
1、定义远程服务接口
2、定义远程服务接口的具体实现
3、将该远程服务注册到RMI命名服务上(指定主机及端口)
启动远程服务所在的jvm线程,此时服务端处于运行中。
客户端:
1、将远程服务接口打包作为客户端的依赖,或者直接复制到客户端
2、根据主机和端口,获得服务注册器的引用
3、注册器根据服务名称查找对应的服务,并返回给客户端(Stub----客户辅助对象)
4、客户对象通过Stub发送请求
5、Stub将调用信息(变量、方法名称等)打包,通过网络将它发送给Skeleton(服务辅助对象)
6、Skeleton将来自Stub的信息解包,找出被调用的方法(以及在哪个对象内),然后调用真正的服务对象上的真正方法
7、服务对象执行方法,获得返回结果,并将结果返回给Skeleton
8、Skeleton将返回结果打包,通过网络返回给Stub(注意返回结果必须是可序列化的)
9、Stub接受到数据后解包,返回给客户对象。
客户端所在的JVM启动后,可以多次调用服务端对象的方法。
3、实例Demo
3.1服务端开发
过程:新建服务端项目,定义接口,接口实现,注册到RMI上
定义接口:接口继承Remote,所有的远程方法都必须声明RemoteExcepyion
1 /** 2 * 远程服务的接口定义 3 * @author Administrator 4 */ 5 public interface HelloService extends Remote{ 6 7 public String sayHello() throws RemoteException; 8 }
接口实现:实现接口,继承UnicastRemoteObject,并实现一个无参构造方法
1 /** 2 * 远程服务接口的具体实现 3 * @author Administrator 4 */ 5 public class HelloServiceImpl extends UnicastRemoteObject implements HelloService{ 6 private static final long serialVersionUID = -5660256561451638005L; 7 // 无参构造方法 8 public HelloServiceImpl() throws RemoteException{} 9 10 @Override 11 public String sayHello() throws RemoteException { 12 return "Hello RMI"; 13 } 14 }
注册对象,并启动JVM
1 public class ServerTest { 2 public static void main(String[] args) throws RemoteException { 3 // 定义服务对象 4 HelloService service = new HelloServiceImpl(); 5 // 获取注册器,指定查找端口 6 Registry registry = LocateRegistry.createRegistry(2002); 7 // 注册对象 8 registry.rebind("HelloService", service); 9 System.out.println("server is ready"); 10 } 11 }
执行程序,通过netstat命令,可查看到2002端口正处于监听状态。
3.2客户端开发
过程:新建客户端项目,复制远程接口定义,获取注册器,查找远程接口实现,请求方法
1 public class ClientTest { 2 public static void main(String[] args) throws RemoteException, NotBoundException { 3 // 根据主机IP和端口获取注册器 4 Registry registry = LocateRegistry.getRegistry("localhost",2002); 5 // 从注册器上查找服务对象 6 HelloService service = (HelloService)registry.lookup("HelloService"); 7 // 直接调用方法 8 String string = service.sayHello(); 9 // 输出远程方法调用的返回结果 10 System.out.println(string); 11 } 12 }
执行程序后,可看到输出结果如下: