图中显示了一个分布式的对象模型。在这个模型中,如果一个对象不仅被本地访问,而且还能够被远程访问,就称为远程对象。

如果一个对象只能被本地访问,就被称为本地对象。

图中白色的椭圆表示本地对象,深色的椭圆表示远程对象。

图中实线表示常规的本地方法调用,虚线表示远程方法调用。

为了保证各个对象之间的可靠地发送消息,该模型的实现通常使用TCP协议作为网络传输层的通信协议。

一般来说远程对象分布在服务器端,提供各种通用的访问。

对象模型的实现系统的功能:

1.把分布在不同节点上的对象之间发送的消息转换为字节序列,这个过程称为编组。

2.通过套接字建立连接并且编组后发送。

3.处理网络连接和传输时候的各种故障。

4.为分布在不同节点上的对象提供分布式垃圾收集机制。

5.为远程方法调用提供安全检查机制。

6.服务端运用多线程或者非阻塞通信机制,确保远程对象具有良好的并发性能,同时被多个客户访问。

7.创建于特定领域相关的各种本地对象和远程对象。

一些现成的,成熟的分布式对象模型的框架:

1.RMI(Remote Method Invoke,远程方法调用):JDK提供一个完善的,简单易用的远程方法调用框架,它要求客户端和服务端都是java程序。

2.CORBA(Common Object Request Broker Architecture,通用对象请求代理体系结构):分布式对象模型的通用框架,允许不同的语言编写

的对象能够彼此通信。

3.SOAP(Simple Object Access Protocol,简单对象访问协议):允许异构的系统之间能够彼此通信,以xml作为通信语言。一个系统能够访问另一个

系统对外公布的web服务。

RMI框架封装了所有底层通信细节,并且解决了编组,分布式垃圾回收,安全检查和并发性等通用问题。开发人员只需要专注于开发与特定问题领域相关的

各种本地对象和远程对象。

RMI对象为远程对象分布生成了客户端代理和服务端代理。位于客户端的代理类叫做存根(Stub),位于服务端的代理类叫做骨架(Skeleton)。

客户端调用远程对象的一个方法的时候,实际上是调用本地的存根对象的对应的方法。

存根对象与远程对象实现了相同的接口。

存根对象采用平台无关的编码方式(java序列化机制)对方法的参数进行编组。

存根对象把以下信息发送给服务器:

1.被访问的远程对象的名字。

2.被调用的方法的名字。

3.编组后的参数的字节序列。

服务器接受到这些信息后,由骨架对象来进行处理:

1.反编组参数。

2.定位要访问的对象。

3.调用远程对象的相应方法。

4.获取方法的结果或者异常信息,进行编组。

5.发送给客户。

创建远程类

远程类就是远程对象所属的类。RMI规范要求远程类必须实现一个接口。此外,为了使得远程类的实例能变成为远程客户提供服务的远程对象,

可以用两种途径中的一种把它导出为远程对象。

1.使远程对象继承java.rmi.server.UnicastRemoteObject类,并且远程类的构造方法必须声明抛出RemoteException。这是最常用的方式,

java语言的语言特征是,在构造一个子类的实例时,java虚拟机会先自动调用UnicastRemoteObject父类的不带参数的构造方法,它的定义如

下:

protected UnicastRemoteObject() throws RemoteException

{

this(0);

}

protected UnicastRemoteObject(int port)throws RemoteException

{

this.port = port;

exportObject((Remote)this,port);

}

由此,UnicastRemoteObject类的构造方法会调用自身的静态方法exportObject(Remote obj,int port)。该方法负责把参数obj指定的对象导出为

远程对象,使得它具有相应的存根,并且使得它能够监听远程客户的请求。参数port指定监听的端口,如果取值为0,表示任意一个匿名端口。

2.如果一个远程对象已经继承了一个类,无法再继承UnicastRemoteObject类,那么可以再构造方法中调用UnicastRemoteObject类的静态

exportObject()方法。同样,远程类的构造方法必须声明抛出RemoteException异常。

远程类的注意事项:

1.远程类的构造方法必须声明抛出RemoteException,如果导出失败,就会抛出这种异常。

2.所有远程方法必须抛出RemoteException。

3.在远程类中可以定义一些本地方法,即没有在远程接口中声明的方法。这些方法无需抛出RemoteException.它们只能被本地调用,不允许被

远程调用。

4.UnicastRemoteObject类覆盖了Object类的hashCode(),equals()和clone()方法。如果一个远程对象继承了UnicastRemoteObject类,就可以

继承它的这些方法。

查找远程对象

1.jdk1.3及以前版本,jdk的bin目录下有一个rmiregistry.exe程序。服务器向rmiregistry注册表注册远程对象。

2.jdk1.3以后,rmi的命名服务API被整合到JNDI(java Naming and Directory Interface,java名字与目录服务)中。

在JNDI中,javax.naming.Context接口声明了注册,查找以及销毁对象的方法。

public void bind(String name,Object obj)

注册对象,把对象与一个名称绑定。如果该名字已经与其他对象绑定,就会抛出NameAlreayBoundException。

public void rebind(String name,Object obj)

如果绑定了,就覆盖绑定。

lookup(String name)

查找对象

unbind(String name)

注销对象

段1:

HelloService helloService = new HelloServiceImpl("service1");

Context namingContext = new InitialContext();

namingContext.rebind("rmi:HelloService1",helloService);

段分析:

默认情况下,InitialContext的rebind()方法会把HelloServiceImpl对象注册到本地主机上的监听1099端口的rmiregistry注册表中,

并且赋予特定的名字HelloService1,该HelloServiceImpl的完整名字为:

rmi://localhost:1099/HelloService1

可以把段1改写为:

段2:

namingContext.rebind("rmi://localhost:1099/HelloService1",helloService);

或者

段3:

namingContext.rebind("rmi://localhost/HelloService1",helloService);

客户端获取远程对象

段4:

Context namingContext = new InitialContext();

HelloService service1 == (HelloService)namingContext.lookup("rmi://localhost/HelloService1");

客户端必须提供完整名字:

rmi://服务端的名字:端口号/对象的注册名字

转载于:https://www.cnblogs.com/xyz-/p/3619035.html

java远程方法调用(RMI)相关推荐

  1. java远程方法调用(rmi)--好_RMI-Java远程方法调用的实现(二)

    System.out.println(); System.out.println( "java.lang.ArithmeticException"); System.out.pri ...

  2. 深究Java中的RMI底层原理

    原博客地址:http://blog.csdn.net/sinat_34596644/article/details/52599688 前言:随着一个系统被用户认可,业务量.请求量不断上升,那么单机系统 ...

  3. java分布式对象RMI应用测试用例

    [0]README 0.1)本文旨在对http://blog.csdn.net/PacosonSWJTU/article/details/50705192  中的代码进行实践(如何部署一个使用RMI框 ...

  4. java安全(三)RMI

    给个关注?宝儿! 给个关注?宝儿! 给个关注?宝儿! 关注公众号:b1gpig信息安全,文章推送不错过 1.RMI 是什么 RMI(Remote Method Invocation)即Java远程方法 ...

  5. java序列化和RMI

    深入了解序列化"契约" 由于Java提供了良好的默认支持,实现基本的对象序列化是件比较简单的事.待序列化的Java类只需要实现Serializable接口即可.Serializab ...

  6. Java EE之RMI

    开始学Java EE,为什么不从Servlet,JSP学起,而偏要选择一个在如今企业级开发中基本上不会直接用到的RMI,是因为大名鼎鼎而又臭名昭著但又不得不学的EJB建立在RMI基础之上.怀揣着李约瑟 ...

  7. java中使用rmi进行远程方法调用

    java中进行远程方法调用,能支持分布式计算.并且可以实现在server的修改,能反应到各个client. 假如server的ip是:192.168.11.2, server端的代码如下: /*** ...

  8. Java代码审计基础——RMI原理和反序列化利用链

    目录 (一)何为RMI (二). RMI的模式与交互过程 0x01 设计模式 0x02 交互过程 0x03  Stub和Skeleton (三)简单的 RMI Demo 1.Server 2.Regi ...

  9. Java I/O中的对象序列化

    Java I/O中的对象序列化 Java对象序列化将那些实现了Serializable接口的对象转换成一个字节序列,并能够以后将这个字节序列完全恢复为原来的对象.利用对象的序列化,可以实现轻量级持久性 ...

最新文章

  1. 异步GridView(ASPxGridView) 特点介绍(2) - 筛选(Filter)、弹出编辑(Editing)
  2. 一地鸡毛 OR 绝地反击,2019年区块链发展指南
  3. c++:栈的基本操作+实例:迷宫求解
  4. C++版数据结构继承关系图
  5. buu 信息化时代的步伐
  6. linux修改jdk环境变量6,Linux CentOS 6.5 使用自带jdk修改环境变量(示例代码)
  7. bootstrap下拉框分页_【Bootstrap】 bootstrap-select2下拉菜单插件
  8. 830. 较大分组的位置
  9. jar k8s 自己的 部署_怎样部署K8S服务器
  10. Template Method (模板方法模式)
  11. 使用pycharm创建Django项目
  12. 语音转写录音转文字哪种更好
  13. 基于单片机的数字万年历设计
  14. 用Java实现图像识别_只需要这三步,用Java也能图片识别
  15. 游戏美术设计中,最难的角色人物如何设计才能吸睛?
  16. mac如何升级python,Mac更新Python
  17. 在线支付(易宝支付)
  18. android 游戏降低画质6,怎么改善安卓游戏画面?
  19. 什么是宏任务、微任务?宏任务、微任务有哪些?又是怎么执行的?
  20. XCTF sherlock WP

热门文章

  1. 95 后新生代 Committer 贺张俭:谈谈年轻人的开源观
  2. kaldi教程_kaldi中特征变换
  3. vSphere6.7创建Windows Server 2016虚拟机及磁盘扩容
  4. UMDF的第一个win10驱动:驱动程序开发环境完善(三)
  5. QDateTimeEdit 用法总结
  6. GIAC全球互联网架构大会
  7. SDN软件定义网络之北向接口概述和REST API设计规范
  8. Zadig 完成 100% 开源:开启软件交付 3.0 时代
  9. npoi 实现类似excel、word自身的加密解密效果
  10. Win·使用迅雷下载资源时中断问题