概念:
  Java RMI 指的是远程方法调用 (Remote Method Invocation)。它是一种机制,能够让在某个 Java 虚拟机上的对象调用另一个 Java 虚拟机中的对象上的方法。可以用此方法调用的任何对象必须实现该远程接口。
  Java RMI不是什么新技术(在Java1.1的时代都有了),但却是是非常重要的底层技术。
  大名鼎鼎的EJB都是建立在rmi基础之上的,现在还有一些开源的远程调用组件,其底层技术也是rmi。
  在大力鼓吹Web Service、SOA的时代,是不是每个应用都应该选用笨拙的Web Service组件来实现,通过对比测试后,RMI是最简单的,在一些小的应用中是最合适的。

RMI远程调用步骤:

  1,客户对象调用客户端辅助对象上的方法

  2,客户端辅助对象打包调用信息(变量,方法名),通过网络发送给服务端辅助对象

  3,服务端辅助对象将客户端辅助对象发送来的信息解包,找出真正被调用的方法以及该方法所在对象

  4,调用真正服务对象上的真正方法,并将结果返回给服务端辅助对象

  5,服务端辅助对象将结果打包,发送给客户端辅助对象

  6,客户端辅助对象将返回值解包,返回给客户对象

  7,客户对象获得返回值

  对于客户对象来说,步骤2-6是完全透明的

服务端类图:
 
  IService接口用于声明服务器端必须提供的服务(即service()方法)
  ServiceImpl类是具体的服务实现类
  Server类是最终负责注册服务器远程对象,以便在服务器端存在骨架代理对象来对客户端的请求提供处理和响应。
 
各个类的源代码如下:

IService接口:

import java.rmi.Remote;
import java.rmi.RemoteException;
public interface IService extends Remote {
//声明服务器端必须提供的服务
String service(String content) throws RemoteException;
}

  创建远程方法接口,该接口必须继承自Remote接口

  Remote 接口是一个标识接口,用于标识所包含的方法可以从非本地虚拟机上调用的接口,Remote接口本身不包含任何方法

  由于远程方法调用的本质依然是网络通信,只不过隐藏了底层实现,网络通信是经常会出现异常的,所以接口的所有方法都必须抛出RemoteException以说明该方法是有风险的。

ServiceImpl实现类:

import java.rmi.RemoteException;
//UnicastRemoteObject用于导出的远程对象和获得与该远程对象通信的存根。
import java.rmi.server.UnicastRemoteObject; public class ServiceImpl extends UnicastRemoteObject implements IService { private String name; /**
* 必须定义构造方法,即使是默认构造方法,也必须把它明确地写出来,因为它必须抛出出RemoteException异常
*/
public ServiceImpl(String name) throws RemoteException {
this.name = name;
} @Override
public String service(String content) {
return "server >> " + content;
}
}

  创建远程方法接口实现类:

  UnicastRemoteObject类的构造函数抛出了RemoteException,故其继承类不能使用默认构造函数,继承类的构造函数必须也抛出RemoteException

  由于方法参数与返回值最终都将在网络上传输,故必须是可序列化的

 Server类:

/**
* Context接口表示一个命名上下文,它由一组名称到对象的绑定组成。
* 它包含检查和更新这些绑定的一些方法。
*/
import javax.naming.Context;
/*
* InitialContext类是执行命名操作的初始上下文。
* 该初始上下文实现 Context 接口并提供解析名称的起始点。
*/
import javax.naming.InitialContext; public class Server {
public static void main(String[] args) {
try {
// 实例化实现了IService接口的远程服务ServiceImpl对象
IService service02 = new ServiceImpl("service02");
// 初始化命名空间
Context namingContext = new InitialContext();
/**
* Naming 类提供在对象注册表中存储和获得远程对远程对象引用的方法 Naming 类的每个方法都可将某个名称作为其一个参数,
* 该名称是使用以下形式的 URL 格式(没有 scheme 组件)的 java.lang.String:
* //host:port/name host:注册表所在的主机(远程或本地),省略则默认为本地主机
* port:是注册表接受调用的端口号,省略则默认为1099,RMI注册表registry使用的著名端口
* name:是未经注册表解释的简单字符串
*/
// 将名称绑定到对象,即向命名空间注册已经实例化的远程服务对象
namingContext.rebind("rmi://localhost/service02", service02);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("服务器向命名表注册了1个远程服务对象!");
}
}

 Client类:

import javax.naming.Context;
import javax.naming.InitialContext; public class Client {
public static void main(String[] args) {
String url = "rmi://localhost/";
try {
Context namingContext = new InitialContext();
// 检索指定的对象。 即找到服务器端相对应的服务对象存根
IService service02 = (IService) namingContext.lookup(url
+ "service02");
Class stubClass = service02.getClass();
System.out.println(service02 + " 是 " + stubClass.getName()
+ " 的实例!");
// 获得本底存根已实现的接口类型
Class[] interfaces = stubClass.getInterfaces();
for (Class c : interfaces) {
System.out.println("存根类实现了 " + c.getName() + " 接口!");
}
System.out.println(service02.service("你好!"));
} catch (Exception e) {
e.printStackTrace();
}
}
}

执行步骤:

  将以上代码保存于某一目录下,
  先运行“start rmiregistry”来启动JDK自带的注册表程序,它用于保存Server类注册的远程对象并允许远程客户端的请求访问;
  然后运行服务器端的Server类,即“start java Server”,该程序向注册表中注册具体的远程对象;
  最后才是运行客户端程序来查找并获得服务器端的远程对象存根,此时才能使用存根对象与服务器进行通信,命令是“java Client”。
  注意:上面命令中的start的功能是重新打开一个DOS窗口。
 
运行结果如下:
 
 
其实整个简单的RMI 应用中各个类的交互时序如下图:

参考复制来源:

http://haolloyin.blog.51cto.com/1177454/332426

http://blog.csdn.net/a19881029/article/details/9465663

http://damies.iteye.com/blog/51778

http://www.blogjava.net/zhenyu33154/articles/320245.html

  还没弄太明白,先攒起来以后看。

 

Java RMI 框架_远程方法调用(2016-08-16)的更多相关文章

  1. (转) Java RMI 框架(远程方法调用)

    "原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://haolloyin.blog.51cto.com/1177454/33 ...

  2. Java RMI 框架(远程方法调用)

    转自:http://haolloyin.blog.51cto.com/1177454/332426 RMI(即Remote Method Invoke 远程方法调用).在Java中,只要一个类exte ...

  3. Java RMI 框架

    RMI(即Remote Method Invoke 远程方法调用).在Java中,只要一个类extends了java.rmi.Remote接口,即可成为存在于服务器端的远程对象,供客户端访问并提供一定 ...

  4. Java 集合框架_上

    集合框架被设计成要满足以下几个目标. 该框架必须是高性能的.基本集合(动态数组,链表,树,哈希表)的实现也必须是高效的. 该框架允许不同类型的集合,以类似的方式工作,具有高度的互操作性. 对一个集合的 ...

  5. Murano Weekly Meeting 2016.08.16

    Meeting time: 2016.August.16 1:00~2:00 Chairperson:  Kirill Zaitsev, from Mirantis Meeting summary: ...

  6. Java 集合框架_中

    Set接口 特点: [1]Set接口表示一个唯一.无序的容器(和添加顺序无关) Set接口常用实现类有 HashSet [1]HashSet是Set接口的实现类,底层数据结构是哈希表. [2]Hash ...

  7. Java 集合框架_下

    Map接口 特点: [1]Map接口称为键值对集合或者映射集合,其中的元素(entry)是以键值对(key-value)的形式存在. [2]Map 容器接口中提供了增.删.改.查的方式对集合进行操作. ...

  8. Java自带RPC实现,RMI框架入门

    Java自带RPC实现,RMI框架入门 首先RMI(Remote Method Invocation)是Java特有的一种RPC实现,它能够使部署在不同主机上的Java对象进行通信与方法调用,它是一种 ...

  9. Java学习---面向对象的远程方法调用[RMI]

    基础知识 分布式计算是一门计算机科学,它研究如何把一个需要非常巨大的计算能力才能解决的问题分成许多小的部分,然后把这些部分分配给许多计算机进行处理,最后把这些计算结果综合起来得到最终的结果. 常见的分 ...

随机推荐

  1. C#读取json数据介绍

    //using System.Web.Script.Serialization; JavaScriptSerializer serializer = new JavaScriptSerializer( ...

  2. UILable自适应frame

    UILabel *textlab = [[UILabel alloc]initWithFrame:CGRectMake(20, 10,ScrollView.frame.size.width - 40, ...

  3. Installing Ubuntu on a Pre-Installed Windows 8 (64-bit) System (UEFI Supported)

    http://askubuntu.com/questions/221835/installing-ubuntu-on-a-pre-installed-windows-8-64-bit-system-u ...

  4. STM32 IAP 在线更新程序 为什么有时行 有时又不行 感觉不可靠 问题解决

    搞了一天才发现 在MDK设置选项中有个"linker"选项卡 , 需要在Project->Options->Linker中将Use Memory Layout from ...

  5. 黑马程序员_<<GUI(图形用户界面)--------1>>

    --------------------ASP.Net+Android+IOS开发..Net培训.期待与您交流! -------------------- 1.  GUI图形用户界面 1.简述 Gra ...

  6. Maven使用第三方jar文件的两种方法 转

    在Maven中,使用第三方库一般是通过pom.xml文件中定义的dependency从远程repository中下载该库.但是如果库文件是公司内部的库,或者在本地而不能通过远程repository下载 ...

  7. (转)Zend Studio 10.6.1破解注册图文详解

    原文来自:http://www.softown.cn/soft/zend-studio/windows/10.6.1#downloads 下面我们以Zend Studio 10.6.1正式版为例来介绍 ...

  8. android考试题

    一.选择题 1. Math.round(11.5)等于多少(    ). Math.round(-11.5) 等于多少(   C  ). A.11 ,-11    B.11 ,-12 C.12 ,-1 ...

  9. 基于RMAN从活动数据库异机克隆(rman duplicate from active DB)

    Oracle 11g RMAN能够实现基于活动数据库进行异机克隆,从而省去需要先备份再ftp到辅助服务器的过程.这一切可以全部交给Oracle来搞定.在克隆期间,Oracle会读取Target DB的 ...

  10. 站在巨人的肩膀上学习Android开发

    我们知道,一開始最好的学习方法是模仿,尤其是模仿巨人. 那说到Android开发的模仿自然就是分析并研究主流程序的布局.实现方法.进而提升自己的技术. 第一招----逆向project 要分析&quo ...