RMI介绍

  远程方法调用(RMI)顾名思义是一台机器上的程序调用另一台机器上的方法。这样可以大致知道RMI是用来干什么的,但是这种理解还不太确切。RMI是Java支撑分布式系统的基石,例如著名的EJB组件。RMI是远程过程调用(RPC)的一种面向对象实现,RMI底层是通过socket通信和对象序列化技术来实现的。这里引用Wikipedia对RMI的介绍:

The Java Remote Method Invocation (Java RMI) is a Java API that performs remote method invocation, the object-oriented equivalent of remote procedure calls (RPC), with support for direct transfer of serialized Java classes and distributed garbage collection.

  1. The original implementation depends on Java Virtual Machine(JVM) class representation mechanisms and it thus only supports making calls from one JVM to another. The protocol underlying this Java-only implementation is known as Java Remote Method Protocol (JRMP).
  2. In order to support code running in a non-JVM context, a CORBA version was later developed.

Usage of the term RMI may denote solely the programming interface or may signify both the API and JRMP, IIOP, or another implementation, whereas the term RMI-IIOP (read: RMI over IIOP) specifically denotes the RMI interface delegating most of the functionality to the supporting CORBA implementation.
The basic idea of Java RMI, the distributed garbage-collection (DGC) protocol, and much of the architecture underlying the original Sun implementation, come from the 'network objects' feature of Modula-3.

RMI基本原理

  RMI的目的就是要使运行在不同的计算机中的对象之间的调用表现得像本地调用一样。RMI 应用程序通常包括两个独立的程序:服务器程序和客户机程序。RMI 需要将行为的定义与行为的实现分别定义, 并允许将行为定义代码与行为实现代码存放并运行在不同的 JVM 上。在 RMI 中, 远程服务的定义是存放在继承了 Remote 的接口中。远程服务的实现代码存放在实现该定义接口的类中。RMI 支持两个类实现一个相同的远程服务接口: 一个类实现行为并运行在服务器上, 而另一个类作为一个远程服务的代理运行在客户机上。客户程序发出关于代理对象的调用方法, RMI 将该调用请求发送到远程 JVM 上, 并且进一步发送到实现的方法中。实现方法将结果发送给代理, 再通过代理将结果返回给调用者。

  RMI 构建三个抽象层, 高层覆盖低层, 分别负责Socket通信, 参数和结果的序列化和反序列化等工作。存根( Stub) 和骨架( Skeleton) 合在一起形成了 RMI 构架协议。下面的引用层被用来寻找各自的通信伙伴, 在这一层还有一个提供名字服务的部分, 称为注册表( registry) 。最下一层是传输层, 是依赖于 TCP/IP 协议实现客户机与服务器的互联。
  

  当客户端调用远程对象方法时, 存根负责把要调用的远程对象方法的方法名及其参数编组打包,并将该包向下经远程引用层、传输层转发给远程对象所在的服务器。通过 RMI 系统的 RMI 注册表实现的简单服务器名字服务, 可定位远程对象所在的服务器。该包到达服务器后, 向上经远程引用层, 被远程对象的 Skeleton 接收, 此 Skeleton 解析客户包中的方法名及编组的参数后, 在服务器端执行客户要调用的远程对象方法, 然后将该方法的返回值( 或产生的异常) 打包后通过相反路线返回给客户端, 客户端的 Stub 将返回结果解析后传递给客户程序。事实上, 不仅客户端程序可以通过存根调用服务器端的远程对象的方法, 而服务器端的程序亦可通过由客户端传递的远程接口回调客户端的远程对象方法。在分布式系统中, 所有的计算机可以是服务器, 同时又可以是客户机。

RMI应用示例

  Remote 接口用于标识其方法可以从非本地虚拟机上调用的接口。任何远程对象都必须直接或间接实现此接口。只有在“远程接口”(扩展 java.rmi.Remote 的接口)中指定的这些方法才可远程使用。 也就是说需要远程调用的方法必须在扩展Remote接口的接口中声名并且要抛出RemoteException异常才能被远程调用。远程对象必须实现java.rmi.server.UniCastRemoteObject类,这样才能保证客户端访问获得远程对象时,该远程对象将会把自身的一个拷贝序列化后以Socket的形式传输给客户端,此时客户端所获得的这个拷贝称为“存根”,而服务器端本身已存在的远程对象则称之为“骨架”。其实此时的存根是客户端的一个代理,用于与服务器端的通信,而骨架也可认为是服务器端的一个代理,用于接收客户端的请求之后调用远程方法来响应客户端的请求。 远程对象的接口和实现必须在客户端和服务器端同时存在并且保持一致才行。

实现代码:

package com.wxisme.rmi;

import java.rmi.Remote;
import java.rmi.RemoteException; /**
*@Description:<p>远程接口定义</p>
*@author 王旭
*@time 2016年3月14日 下午4:53:48
*/
public interface HelloDefine extends Remote { public String helloWorld() throws RemoteException; public String sayHello(String name) throws RemoteException; }
package com.wxisme.rmi;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject; /**
*@Description:<p>远程接口实现</p>
*@author 王旭
*@time 2016年3月14日 下午4:57:50
*/
public class HelloDefineImp extends UnicastRemoteObject implements HelloDefine { /**
*
*/
private static final long serialVersionUID = 1L; public HelloDefineImp() throws RemoteException {
super();
} public String helloWorld() throws RemoteException {
return "Hello AlphaGo!";
} public String sayHello(String name) throws RemoteException {
return "Hello" + name +"!";
} }
package com.wxisme.rmi;

import java.net.MalformedURLException;
import java.rmi.AlreadyBoundException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry; /**
*@Description:<p>服务端绑定</p>
*@author 王旭
*@time 2016年3月14日 下午4:59:33
*/
public class HelloServer { HelloDefine hello; public void server() throws RemoteException, MalformedURLException, AlreadyBoundException {
hello = new HelloDefineImp(); //远程对象注册表实例
LocateRegistry.createRegistry(8888);
//把远程对象注册到RMI注册服务器上
Naming.bind("rmi://localhost:8888/Hello", hello);
System.out.println("server:对象绑定成功!");
} }
package com.wxisme.rmi;

import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException; /**
*@Description:<p>客户端调用</p>
*@author 王旭
*@time 2016年3月14日 下午5:08:51
*/public class HelloClient { public HelloDefine hello; public void client() throws MalformedURLException, RemoteException, NotBoundException {
//在RMI注册表中查找指定对象
hello = (HelloDefine) Naming.lookup("rmi://localhost:8888/Hello");
//调用远程对象方法
System.out.println("client:");
System.out.println(hello.helloWorld());
System.out.println(hello.sayHello("神之一手"));
} }
package com.wxisme.rmi;

import java.net.MalformedURLException;
import java.rmi.AlreadyBoundException;
import java.rmi.NotBoundException;
import java.rmi.RemoteException; import org.junit.Test; /**
*@Description:<p>测试</p>
*@author 王旭
*@time 2016年3月14日 下午5:14:36
*/
public class RMITest { @Test
public void testServer() throws RemoteException, MalformedURLException, AlreadyBoundException {
HelloServer server = new HelloServer();
server.server();
while(true);
} @Test
public void testClient() throws MalformedURLException, RemoteException, NotBoundException {
HelloClient client = new HelloClient();
client.client();
} }

运行结果:

参考资料:

Wikipedia RMI:https://en.wikipedia.org/wiki/Java_remote_method_invocation

Java RMI 框架:http://haolloyin.blog.51cto.com/1177454/332426/

《基于 RMI 的文件上传与下载的实现》程晓锦, 徐秀花

http://www.cnblogs.com/wxisme/p/5296441.html

远程方法调用(RMI)原理与示例 (转)的更多相关文章

  1. java RMI原理详解

    java本身提供了一种RPC框架——RMI(即Remote Method Invoke 远程方法调用),在编写一个接口需要作为远程调用时,都需要继承了Remote,Remote 接口用于标识其方法可以 ...

  2. Java多线程系列--“JUC锁”10之 CyclicBarrier原理和示例

    概要 本章介绍JUC包中的CyclicBarrier锁.内容包括:CyclicBarrier简介CyclicBarrier数据结构CyclicBarrier源码分析(基于JDK1.7.0_40)Cyc ...

  3. Java多线程系列--“JUC锁”11之 Semaphore信号量的原理和示例

    概要 本章,我们对JUC包中的信号量Semaphore进行学习.内容包括:Semaphore简介Semaphore数据结构Semaphore源码分析(基于JDK1.7.0_40)Semaphore示例 ...

  4. spring原理案例-基本项目搭建 03 创建工程运行测试 spring ioc原理实例示例

    下面开始项目的搭建 使用 Java EE - Eclipse 新建一 Dynamic Web Project Target Runtime 选 Apache Tomcat 7.0(不要选 Apache ...

  5. 格式化字符串攻击原理及示例.RP

    格式化字符串攻击原理及示例 一.类printf函数簇实现原理 类printf函数的最大的特点就是,在函数定义的时候无法知道函数实参的数目和类型. 对于这种情况,可以使用省略号指定参数表. 带有省略号的 ...

  6. silverlight漂亮的文件上传进度显示原理及示例

    silverlight漂亮的文件上传进度显示原理及示例 作者:chenxumi 出处:博客园  2009/11/27 13:37:11 阅读 1219  次 概述:在网站根目录web.config里配 ...

  7. PHP服务器端API原理及示例讲解(接口开发)

    http://www.jb51.net/article/136816.htm 下面小编就为大家分享一篇PHP服务器端API原理及示例讲解(接口开发),具有很好的参考价值,希望对大家有所帮助 相信大家都 ...

  8. 远程方法调用(RMI)原理与示例

    RMI介绍 远程方法调用(RMI)顾名思义是一台机器上的程序调用另一台机器上的方法.这样可以大致知道RMI是用来干什么的,但是这种理解还不太确切.RMI是Java支撑分布式系统的基石,例如著名的EJB ...

  9. RMI原理及简单示例

    分布式对象 在学习 RMI 之前,先来分布式对象(Distributed Object):分布式对象是指一个对象可以被远程系统所调用.对于 Java 而言,即对象不仅可以被同一虚拟机中的其他客户程序( ...

随机推荐

  1. Org-mode五分钟教程ZZZ - Kaka Abel的日志 - 网易博客

    Org-mode五分钟教程ZZZ - Kaka Abel的日志 - 网易博客 Org-mode五分钟教程ZZZ  

  2. php 如何在有限的内存中读取大文件

    突然遇到了一个要读取超过80M文件的需求,很悲剧的,不管是file_get_content还是file什么的,都会将读取的文件一次性加载到内存中. 正常情况下,我们可以使用fseek来读取,好处就是不 ...

  3. cocos2d-x 3.0 使用最新物理引擎的一个源代码实例

    1.碰撞函数參数由两个变成一个了 2.检測不到碰撞.须要设置那三个參数.同一时候还要设置成动态的. body进行设置. 3.初始入口文件也发生了改变. 附录上我近期调试好的cocos2d-x 3.1 ...

  4. 有时候碰到String赋值就出错,原因有三

    1. String所在的对象,根本就不存在(不是String不存在,而是它所属的类对象不存在) 2. 增加一个String作为类元素后,运行直接就崩溃.一次又一次找原因,结果发现,只需要完全重编译就行 ...

  5. 图像编程学习笔记2——bmp位图平移

    以下文字内容copy于<<数字图像处理编程入门>>,code为自己实现,是win32控制台程序. 2.1 平移 平移(translation)变换大概是几何变换中最简单的一种了 ...

  6. 主流JavaScript框架(Dojo、Google Closure、jQuery、Prototype、Mootools和YUI)的分析和对比

    本文主要选取了目前比较流行的JavaScript框架Dojo.Google Closure.jQuery.Prototype.Mootools和YUI进行对比,主要是根据网上的资料整理而成,希望可以供 ...

  7. VS2010-win32下cocos2dx控制台打印的方法

    在xcode中  直接使用printf 或者 cout<<""<<endl;可以直接在控制台打印 但是在VS2010 却死活不好用   真郁闷 ------ ...

  8. Otacle表查询

    1    查询表结构       语法:desc 表      2    查询全部列       语法:select * from 表名      3    查询指定列       语法:select ...

  9. ARM架构和编程-4

    ARM中断异常处理: ARM系统中止品种:按中断处理降序排列优先级:重置.数据访问中止.高速中断请求.外部中断请求.预取中止.令.软件中断. ARM体系中的异常中断向量表: 0x0 复位 0x4 没有 ...

  10. fastdfs storage server的设计与实现

     fastdfs是一个针对互联网应用设计的分布式文件系统.具有架构简单.结构清晰.代码量小等特点. 详细的介绍及架构请參考分布式文件系统FastDFS架构剖析(http://www.program ...