java远程方法调用(RMI)
图中显示了一个分布式的对象模型。在这个模型中,如果一个对象不仅被本地访问,而且还能够被远程访问,就称为远程对象。
如果一个对象只能被本地访问,就被称为本地对象。
图中白色的椭圆表示本地对象,深色的椭圆表示远程对象。
图中实线表示常规的本地方法调用,虚线表示远程方法调用。
为了保证各个对象之间的可靠地发送消息,该模型的实现通常使用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)相关推荐
- java远程方法调用(rmi)--好_RMI-Java远程方法调用的实现(二)
System.out.println(); System.out.println( "java.lang.ArithmeticException"); System.out.pri ...
- 深究Java中的RMI底层原理
原博客地址:http://blog.csdn.net/sinat_34596644/article/details/52599688 前言:随着一个系统被用户认可,业务量.请求量不断上升,那么单机系统 ...
- java分布式对象RMI应用测试用例
[0]README 0.1)本文旨在对http://blog.csdn.net/PacosonSWJTU/article/details/50705192 中的代码进行实践(如何部署一个使用RMI框 ...
- java安全(三)RMI
给个关注?宝儿! 给个关注?宝儿! 给个关注?宝儿! 关注公众号:b1gpig信息安全,文章推送不错过 1.RMI 是什么 RMI(Remote Method Invocation)即Java远程方法 ...
- java序列化和RMI
深入了解序列化"契约" 由于Java提供了良好的默认支持,实现基本的对象序列化是件比较简单的事.待序列化的Java类只需要实现Serializable接口即可.Serializab ...
- Java EE之RMI
开始学Java EE,为什么不从Servlet,JSP学起,而偏要选择一个在如今企业级开发中基本上不会直接用到的RMI,是因为大名鼎鼎而又臭名昭著但又不得不学的EJB建立在RMI基础之上.怀揣着李约瑟 ...
- java中使用rmi进行远程方法调用
java中进行远程方法调用,能支持分布式计算.并且可以实现在server的修改,能反应到各个client. 假如server的ip是:192.168.11.2, server端的代码如下: /*** ...
- Java代码审计基础——RMI原理和反序列化利用链
目录 (一)何为RMI (二). RMI的模式与交互过程 0x01 设计模式 0x02 交互过程 0x03 Stub和Skeleton (三)简单的 RMI Demo 1.Server 2.Regi ...
- Java I/O中的对象序列化
Java I/O中的对象序列化 Java对象序列化将那些实现了Serializable接口的对象转换成一个字节序列,并能够以后将这个字节序列完全恢复为原来的对象.利用对象的序列化,可以实现轻量级持久性 ...
最新文章
- 异步GridView(ASPxGridView) 特点介绍(2) - 筛选(Filter)、弹出编辑(Editing)
- 一地鸡毛 OR 绝地反击,2019年区块链发展指南
- c++:栈的基本操作+实例:迷宫求解
- C++版数据结构继承关系图
- buu 信息化时代的步伐
- linux修改jdk环境变量6,Linux CentOS 6.5 使用自带jdk修改环境变量(示例代码)
- bootstrap下拉框分页_【Bootstrap】 bootstrap-select2下拉菜单插件
- 830. 较大分组的位置
- jar k8s 自己的 部署_怎样部署K8S服务器
- Template Method (模板方法模式)
- 使用pycharm创建Django项目
- 语音转写录音转文字哪种更好
- 基于单片机的数字万年历设计
- 用Java实现图像识别_只需要这三步,用Java也能图片识别
- 游戏美术设计中,最难的角色人物如何设计才能吸睛?
- mac如何升级python,Mac更新Python
- 在线支付(易宝支付)
- android 游戏降低画质6,怎么改善安卓游戏画面?
- 什么是宏任务、微任务?宏任务、微任务有哪些?又是怎么执行的?
- XCTF sherlock WP
热门文章
- 95 后新生代 Committer 贺张俭:谈谈年轻人的开源观
- kaldi教程_kaldi中特征变换
- vSphere6.7创建Windows Server 2016虚拟机及磁盘扩容
- UMDF的第一个win10驱动:驱动程序开发环境完善(三)
- QDateTimeEdit 用法总结
- GIAC全球互联网架构大会
- SDN软件定义网络之北向接口概述和REST API设计规范
- Zadig 完成 100% 开源:开启软件交付 3.0 时代
- npoi 实现类似excel、word自身的加密解密效果
- Win·使用迅雷下载资源时中断问题