RMI原理
一、分布式对象
在学习 RMI 之前,先来分布式对象(Distributed Object):分布式对象是指一个对象可以被远程系统所调用。对于 Java 而言,即对象不仅可以被同一虚拟机中的其他客户程序(Client)调用,也可以被运行于其他虚拟机中的客户程序调用,甚至可以通过网络被其他远程主机之上的客户程序调用。
下面的图示说明了客户程序是如何调用分布式对象的:

从图上我们可以看到,分布式对象被调用的过程是这样的:
1. 客户程序调用一个被称为 Stub (存根)的客户端代理对象。该代理对象负责对客户端隐藏网络通讯的细节。Stub 知道如何通过网络套接字(Socket)发送调用,包括如何将调用参数转换为适当的形式以便传输等。
2. Stub 通过网络将调用传递到服务器端,也就是分布对象一端的一个被称为 Skeleton(骨干) 的代理对象。同样,该代理对象负责对分布式对象隐藏网络通讯的细节。Skeleton 知道如何从网络套接字(Socket)中接受调用,包括如何将调用参数从网络传输形式转换为 Java 形式等。
3. Skeleton 将调用传递给分布式对象。分布式对象执行相应的调用,之后将返回值传递给 Skeleton,进而传递到 Stub,最终返回给客户程序。
这个场景基于一个基本的法则,即行为的定义和行为的具体实现相分离。如图所示,客户端代理对象 Stub 和分布式对象都实现了相同的接口,该接口称为远程接口(Remote Interface)。正是该接口定义了行为,而分布式对象本身则提供具体的实现。对于 Java RMI 而言,我们用接口(interface)定义行为,用类(class)定义实现。
二、RMI架构
RMI(Remote Method Invoke远程方法调用)。在Java中,只要一个类extends了java.rmi.Remote接口,即可成为存在于服务器端的远程对象,供客户端访问并提供一定的服务。同时,远程对象必须实现java.rmi.server.UniCastRemoteObject类,这样才能保证客户端访问获得远程对象时,该远程对象将会把自身的一个拷贝以Socket的形式传输给客户端,此时客户端所获得的这个拷贝称为“存根”,而服务器端本身已存在的远程对象则称之为“骨架”。其实此时的存根是客户端的一个代理,用于与服务器端的通信,而骨架也可认为是服务器端的一个代理,用于接收客户端的请求之后调用远程方法来响应客户端的请求。
RMI框架如下图所示:

1. Stub/Skeleton 层:该层提供了客户程序和服务程序彼此交互的接口。
2. 远程引用(Remote Reference)层:这一层相当于在其之上的 Stub/Skeleton 层和在其之下的传输协议层之前的中间件,负责处理远程对象引用的创建和管理。
3. 传输协议(Transport Protocol) 层:该层提供了数据协议,用以通过线路传输客户程序和远程对象间的请求和应答。
Java RMI 的客户程序使用客户端的 Stub 向远程对象请求方法调用;服务器对象则通过服务器端的 Skeleton 接受请求。

整个调用过程如下:客户端从服务器端下载stub到本地,stub把客户端的参数序列化后,传至远程引用层;远程引用层根据RMI协议转换为传输层数据,通过传输层把数据传到服务器端;服务器端接收到从传输层传过来的数据,通过远程引用层通过RMI协议进行转换,Skeleton 把参数反序列化后传递给服务器端的方法调用。如果方法调用产生异常或返回值再经由Skeleton 序列化给客户端,客户端再反序列化
Stub和Skeleton在什么位置产生
从JDK5.0以后,这两个类就不需要rmic来产生了 ,而是有JVM自动处理,实际上他们还是存在的。Stub存在于客户端,作为客户端的代理,让我们总是认为客户端产生了stub,接口没有作用。实际上stub类是通过Java动态类下载机制下载的,它是由服务端产生,然后根据需要动态的加载到客户端,如果下次再运行这个客户端该存根类存在于classpath中,它就不需要再下载了,而是直接加载。(具体的内部细节,需要参考Sun 的Rmi - Java Remote Method Invocation – Specification)。总的来说,stub是在服务端产生的,如果服务端的stub内容改变,那么客户端的也是需要同步更新。
Stub和公共接口interface(远程对象的功能)的关系
一个服务如果没有合适的存根类,客户就没有办法去调用远程的接口,RMI使用存根来返 回引用远程对象接口的参数。在类的关系中,接口是不能实例化的,但是它可以指向一个实现该接口的实例。存根和接口就是这种关系,而存根类的实例就是在:lookup ()方法 调用时加载、实例的。接口只是告诉JVM,内存中这片的字节码中,这几个方法我可以调用。
创建RMI流程
建立RMI的流程如下:
1. 通过分析需求定义远程接口(客户端和服务器端公用的),此接口必须扩展java.rmi.Remote,且远程方法必须声明抛出 java.rmi.RemoteException 异常,或者该异常的超类(Superclass)。
2. 服务器端实现远程接口,为了不手动生成stub需要继承UnicastRemoteObject类,并调用其构造器;
3. 服务器端注册服务并启动;
4. 客户端查询服务并调用远程方法;

三、代码示例
分别建立三个项目:服务器端(DemoRMI.Server)、客户端(DemoRMI.Client)和远程接口(DemoRMI.RmoteInterface),如下图:

DemoRMI.RmoteInterface中的IHello.java

DemoRMI.Server中的HelloImpl.java

DemoRMI.Server中的App.java

DemoRMI.Client中的App.java:


RMI原理的更多相关文章
- java RMI原理详解
java本身提供了一种RPC框架——RMI(即Remote Method Invoke 远程方法调用),在编写一个接口需要作为远程调用时,都需要继承了Remote,Remote 接口用于标识其方法可以 ...
- RMI原理及简单示例
分布式对象 在学习 RMI 之前,先来分布式对象(Distributed Object):分布式对象是指一个对象可以被远程系统所调用.对于 Java 而言,即对象不仅可以被同一虚拟机中的其他客户程序( ...
- RMI原理及简单demo
1 简介 RMI是远程方法调用的简称,它能够帮助我们查找并执行远程对象的方法.通俗地说,远程调用就象将一个class放在A机器上,然后在B机器中调用这个class的方法. 2 概念 其他机器需要调用的 ...
- RMI原理揭秘之远程对象
讨论开始之前,我们先看看网上的一个例子,这个例子我腾抄了一分,没有用链接的方式,只是为了让大家看得方便,如有侵权,我立马***. 定义远程接口: 1 2 3 4 5 6 package com.guo ...
- 系统间通信(8)——通信管理与RMI 上篇
1.概述 在概述了数据描述格式的基本知识.IO通信模型的基本知识后.我们终于可以进入这个系列博文的重点:系统间通信管理.在这个章节我将通过对RMI的详细介绍,引出一个重要的系统间通信的管理规范RPC, ...
- Java RMI(远程方法调用)开发
参考 https://docs.oracle.com/javase/7/docs/platform/rmi/spec/rmi-arch2.html http://www.cnblogs.com/wxi ...
- K:java中的RMI(Remote Method Invocation)
相关介绍: RMI全称是Remote Method Invocation,即远程方法调用.它是一种计算机之间利用远程对象互相调用,从而实现双方通讯的一种通讯机制.使用这种机制,某一台计算机(虚拟机) ...
- Java——RMI
之前分布式系统调用用的是比较老的EJB,当时还是作为服务调用方,去调用别的系统的服务.最近发现新公司里面,用的是RMI,查了下发现EJB的底层实现就是RMI,也算是熟悉了... 一,使用JDK 中的R ...
- 每日扫盲(一):java的rmi
JAVA RMI 原理和使用浅析 本地对象调用 我们先看看本地对象方法的调用: ObjectClass objectA = new ObjectClass(); String retn = objec ...
随机推荐
- 未能加载文件或程序集“WcfService”或它的某一个依赖项。试图加载格式不正确的程序。
“/”应用程序中的服务器错误. 未能加载文件或程序集“WcfService”或它的某一个依赖项.试图加载格式不正确的程序. 说明: 执行当前 Web 请求期间,出现未经处理的异常.请检查堆栈跟踪信息, ...
- #pragma once 与 #ifndef 解析(转载)
正在入门驱动编程,遇到一个小问题,如下详细解释. 原文链接:#pragma once 与 #ifndef 解析 http://www.cnblogs.com/hokyhu/archive/2009/0 ...
- Java内存管理原理及内存区域详解
一.概述 Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干不同的数据区域,这些区域都有各自的用途以及创建和销毁的时间.Java虚拟机所管理的内存将会包括以下几个运行时数据区域,如下 ...
- Hadoop,HBase,Zookeeper源码编译并导入eclipse
基本理念:尽可能的参考官方英文文档 Hadoop: http://wiki.apache.org/hadoop/FrontPage HBase: http://hbase.apache.org/b ...
- 独树一帜的字符串匹配算法——RK算法
参加了雅虎2015校招,笔试成绩还不错,谁知初面第一题就被问了个字符串匹配,要求不能使用KMP,但要和KMP一样优,当时瞬间就呵呵了.后经过面试官的一再提示,也还是没有成功在面试现场写得.现将该算法记 ...
- JS 格式化日期
function formatDate(date){ var year=date.getFullYear(); var month=date.getMonth()+1; var date=date.g ...
- Python解释器
当我们编写Python代码时,我们得到的是一个包含Python代码的以.py为扩展名的文本文件.要运行代码,就需要Python解释器去执行.py文件. 由于整个Python语言从规范到解释器都是开源的 ...
- [支付]银联支付(对jdk有要求,最好直接使用jdk7)
数据打包发送到银联服务端,银联返回一个html页面,打开这个页面会自动跳转到银联的支付界面,支付完成后会有前台通知和后台通知,需要注意的是后台通知地址的ip必须是公网ip(广域网ip).这个时候需要配 ...
- 怎样在Java中实现基本数据类型与字符之间的转换
摘要:在我们对Java的学习当中数据类型之间的转换,是我们常见的事,我们也都知道基本数据类型之间有自动转换和强制转换,在int . short . long .float .double之间的转 ...
- squid 安装、配置、优化
官方网站:http://www.squid-cache.org 下载路径:wget http://www.squid-cache.org/Versions/v3/3.0/squid-3.0.STABL ...