RMI的基本概念和编程简介.doc_第1页
RMI的基本概念和编程简介.doc_第2页
RMI的基本概念和编程简介.doc_第3页
RMI的基本概念和编程简介.doc_第4页
RMI的基本概念和编程简介.doc_第5页
已阅读5页,还剩3页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

RMI的基本概念和编程简介RMI的基本概念Java RMI(Remote Method Invocation)-Java的远程方法调用是Java所特有的分布式计算技术,它允许运行在一个Java虚拟机上的对象调用运行在另一个Java虚拟机上的对象的方法,从而使Java编程人员可以方便地在网络环境中作分布式计算。面向对象设计要求每个任务由最适合该任务的对象执行,RMI将这个概念更深入了一步,使任务可以在最适合该任务的机器上完成。RMI定义了一组远程接口,可以用于生成远程对象。客户机可以象调用本地对象的方法一样用相同的语法调用远程对象。RMI API提供的类和方法可以处理所有访问远程方法的基础通信和参数引用要求的串行化。远程方法调用类似于Sun公司1985年提出的远程过程调用(RPC)特征。RPC也要求串行化参数和返回数值数据,但由于没有涉及对象,情况比较简单。Sun开发了外部数据表示(XDR)系统,支持数据串行化。RPC和RMI之间的一个重要差别是RPC用快速而不够可靠的UDP协议,RMI用低速而可靠的TCP/IP协议。远程方法调用(RMI)和CORBA都是分布式计算技术,在进行分布式时各有其优缺点,为了有助于了解RMI的特点和用途,有必要讨论一下CORBA和RMI的区别。CORBA(Common Object Request Broker Architecture)是OMG的Object Management Architecture(对象管理结构),它是面向对象的分布式系统建立所依据的标准。CORBA被设计成一个能供所有编程语言使用的一个开放性说明,就是说一个机器上的Java客户可以要求另一个用SmallTalk或C+的机器服务。正是由于这种语言的独立性使得CORBA这么灵活和吸引人。为了适应语言独立性,CORBA采用了非常通用的标准作为其接口。在不同的语言中,远程调用、签名和对象的引入有各自不同的定义,所以CORBA必须尽可能的中立和开放。正是这种通用性是CORBA的一个弱点。当开发人员都采用CORBA时,他们要用一种新的标准定义语言接口,它要求开发者学习新的编程接口,从而减小了远程模型的透明性。RMI是为仅在Java对Java的分布式计算中而开发的。远程调用的标准是为了Java和应用Java的自然Java签名和调用而开发的,这使得RMI对Java的开发者相当透明而且易于实现。RMI用Java语言紧密集成从而同CORBA相比能够提供非常好的容错能力及对异常的处理。尽管Java的RMI标准不像CORBA那样语言独立,但Java本身是一个独立的平台,这就使RMI在跨平台的分布软件开发中是一个很好的选择。RMI是Java语言在分布式计算上的基本模型,很多Java的分布式系统,包括我们要学习的EJB,都是建立在RMI的思想上的。RMI系统的一般结构RMI系统包括3层,端头/框架层(Stubs/Skeletons)、远程应用层(Remote Reference Layer)和传送层(Transport),如图所示:客户机调用远程方法时,请求用客户机的端头调用。客户机引用端头作为远程机上对象的代表。上图所示的所有基础功能在客户机上都看不到。端头代码由rmic编译器长生,并用远程引用层(RRL)将方法调用请求传递到服务器对象。1) 端头(Stub)端头就是代表远程对象的客户机方代理,定义远程对象版本支持的所有接口。端头在客户机上运行的程序像本地对象一样引用,从客户机来看与本地对象相似,它还保持与服务器方对象的连接。客户机方的远程应用层返回端头的调动流。客户方的RRL用调用流与服务器方的RRL通信。端头将参数数据串行化,将串行化的数据传递到调动流。 执行完远程方法调用后,RRL将串行化的返回值送回端头,负责反串行化。2) 框架(Skeleton)框架是与服务器方RRL接口的服务器方构件。框架接受客户机方RRL的方法调用请求。服务器方RRL要反调动发送到远程方法的任何变元。然后框架调用服务器方的实际对象实现。框架还负责接收来自远程对象的返回值并将其调动到调动流中。3) 远程引用层(Remote Reference Layer)远程引用层(RRL)负责维护不与具体端头或框架模型相关的独立应用协议。这个灵活性使RRL的改变不会影响另外两层。RRL涉及低级传送接口,负责向端头和框架层提供流。RRL通过传送层用客户机方面和服务器方构件通信。客户机方构件包含远程服务器的特定信息。这个信息传递到服务器方构件,因此只依赖于服务方RRL。服务器方RRL负责引用语法和处理这些语法之后再向框架发送远程方法调用。客户机和服务器方构件之间的通信由传送层处理。4) 传送层(Transport Layer)传送层负责建立并维护客户机和服务器之间的连接。传送层包括4个抽象:端点(endpoint)抽象用于引用包含Java虚拟机的地址空间,是具体传送接口的引用。通道(channel)抽象是两个地址空间之间的通路。这个通路负责管理客户机和服务器之间的各种连接。连接(connection)抽象是客户机和服务器之间数据(变元和返回值)传送的抽象。传送(transport)抽象负责建立本地地址空间和远程端点之间的通道。传送抽象还负责接收到包含抽象的地址空间的输入连接。传送层建立连接,管理现有连接和处理地址空间中的远程对象。传送层接收客户机方RRL请求时,它寻找请求的远程对象的RMI服务器,然后传送层建立到这个服务器的接插连接。接着,传送层将建立的连接传递到客户机RRL上并将远程对象的引用加入内部表。这时客户机即连接到服务器。传送层监视连接的活性。如果经过较长时间连接毫无动静,则传送层负责关掉这个连接。RMI的分层结构不仅在概念上显得很清晰和合理,而且也给我们开发RMI应用程序提供了极大的方便,设想一下,如果我们需要去了解传送层的细节,那么,RMI的应用程序的开发将会是一件很艰巨的任务。幸好,我们没有必要那么做,RMI的分层结构是我们可以在高层进行开发而不必要去理会底层的细节,其实,开发RMI应用程序和开发普通的Java应用程序几乎没有什么区别。使用RMI构造分布式应用系统RMI应用程序通常由两个独立的程序构成:一个server和一个client。一个典型的server应用程序创建一些远程对象,使它们可被引用,并等待客户端调用这些远程对象的方法。一个典型的client应用程序得到server上的一个或多个远程对象的远程引用,并调用这些对象的方法。RMI提供了server和client通信和传递信息的机制。这样的应用程序叫做一个分布式对象应用程序。分布式对象应用程序需要定位远程对象:应用程序可以使用两种机制之一来获得远程对象的引用。应用程序可以使用RMI的命名工具rmiregistry来注册它的远程对象,或者象进行一般操作一样传递和返回远程对象的引用。和远程对象通信:远程对象之间的通信细节由RMI来处理。对程序员来说,远程通信就像一个标准的Java方法调用。装载被传递对象的类字节码:因为RMI允许调用者向远程对象传递对象,所以它提供了传递数据和装载一个对象代码的必要机制。下图描述了一个使用注册机制获得一个远程对象引用的RMI分布式应用程序。Server方调用注册器将一个远程对象和一个名字联系起来。Client方在Server的注册器中通过名字寻找远程对象并调用其方法。该图也显示了RMI系统使用一个现有web server来装载类字节码,在需要时在server和client之间传输字节码。RMI的一个重要而独特的特性是它能动态下载一个在接收者的虚拟机中未定义的对象类的字节码(或简单代码)。一个对象的类型和行为,这些原来只能在一个单一的虚拟机中可以得到的信息,可以被传递给另一个可能是远程的虚拟机。RMI将对象连同其真实的类型一起传递,所以当这些对象被传递给另一个虚拟机时其行为不发生改变。这就允许将新类型引入一个远程的虚拟机,从而动态扩展一个应用程序的行为。像其他应用程序一样,一个使用Java RMI的分布式应用程序也由接口和类组成。接口中定义一些方法,类实现接口中定义的方法,并定义一些其他的方法。在一个分布式应用程序中,一些实现需要驻留在不同的虚拟机上。具有可以跨虚拟机调用的方法的对象叫做远程对象。一个对象通过实现一个远程接口成为远程对象,它具有如下特征:1) 一个远程接口由java.rmi.Remote派生。2) 接口中的每个方法都要声明抛出java.rmi.RemoteException,除了 其他特殊的例外之外。当对象从一个虚拟机传递给另一个虚拟机时,RMI对远程对象的处理与非远程对象是不相同的。对于远程对象,RMI传递给接收方虚拟机一个远程端头,而不是一个对象的拷贝。端头作为远程对象的本地标识或代理,对于调用方来说,是一个远程引用。调用方调用本地端头的一个方法,由本地端头负责处理对远程对象的方法调用。一个远程对象的端头实现了与远程对象实现的相同的接口。这就允许一个端头可以被转换为远程对象所实现的任意一个接口。这也意味着只有定义在远程接口中的方法才可以在接收方虚拟机上被调用。当你使用RMI来开发一个分布式应用时,需要遵守下面的步骤: 1) 设计和实现你的分布式应用的组件。首先,决定应用程序的结构,哪些组件是本地对象,哪些应该可以远程访问。这个步骤包括:定义远程接口:一个远程接口定义了可以被客户端远程调用的方法。客户端针对远程接口编程,而不是针对实现这些接口的类。设计这样的接口的一部分工作取决于作为这些方法的参数和返回值的本地对象。如果还没有这样的接口和类的存在,就需要自己定义。实现远程对象:远程对象必须实现一个或多个远程接口。远程对象类可能包括其他接口(本地的或远程的)和方法(仅在本地可得到的)的实现。如果有本地类作为这些方法的参数或返回值,这些类也必须被实现。 实现客户端:使用远程对象的客户可以在远程接口被定义后的任何时候实现,包括远程对象被展开后。2) 编译源程序并生成端头。这是一个两步操作过程。第一步,使用Javac编译器来编译源文件,其中包含了远程接口及其实现部分、server类和client类。第二步,使用rmic编译器来生成远程对象的端头。RMI使用一个远程对象的端头类来作为客户端的代理,从而使客户端可以同一个特定的远程对象通信。3) 使得类可以通过网络访问。这一步使一切与远程接口有关的类文件、端头、其他任意的需要下载到客户方的类可以通过一个web server访问。 4) 启动应用程序。启动应用程序包括运行RMI远程对象注册程序,服务器,客户端。用RMI来构造分布式应用系统是不是很简单的一件事情?的确,RMI使我们可以自己编写分布式的应用系统,在没有RMI之前这种事情是难于想象的。一个简单的RMI的例子一个虽然简单但是完整的RMI分布式应用程序的例子,该程序由两部分组成;包括远程对象的server方和调用server方的远程方法sayHello()获得字符串Hello World并输出该字符串的client方。1 构造一个远程接口Hello:package hello; public interface Hello extends java.rmi.Remote /rmi应用程序必须继承自java.rmi.RemoteString sayHello() throws java.rmi.RemoteException ; /定义可以远程调用的接口2 完成server方程序,定义HelloImpl类实现Hello接口:package hello;import java.rmi.*;import java.rmi.server.UnicastRemoteObject;public class HelloImpl extends UnicastRemoteObject implements Hello /实现Hello接口private String name;public HelloImpl (String s ) throws java.rmi.RemoteExceptionsuper(); /调用父类的构造函数name = s;public String sayHello() throws RemoteException return Hello world!; /实现Hello接口定义的方法public static void main ( String args )System.setSecurityManager ( new RMISecurityManager() ); /设置RMI程序需要的安全策略tryHelloImpl obj = new HelloImpl(HelloServer); /生成一个HelloImpl的实例Naming.rebind(HelloServer, obj); /将这个实例绑定到一个名字上System.out.println(HelloImpl created and bound in the registry to the name HelloServer); catch (Exception e)System.out.println(HelloImpl.main: an exception occured:);e.printStackTrace(); /产生异常的话,打印出出错信息server方生成一个远程对象并和一个可和客户对话的名称HelloServer绑定。Client端可以根据该名称寻找相应的远程对象,进而调用其远程方法。3 完成client方程序package hello;import java.rmi.*; public class HelloClient public static void main(String args)System.setSecurityManager(new RMISecurityManager() ); /设置RMI需要的安全策略tryHello obj = (Hello) Naming.lookup(HelloServer); /从服务端获得一个Hello的远程对象String message = obj.sayHello(); /远程调用Hello的方法System.out.println(message); /将输出结果打印 catch (Exception e)System.out.println(Hello client : an exception occured);e.printStackTrace(); /若有异常,输出异常信息 client利用java.rmi包中的Naming类的lookup()方法获得远程对象obj,然后调用其远程方法sayHello()获得字符串Hello World,并输出到屏幕上。要运行这几个程序,还有一些工作要做,这几个程

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论