java_RMI技术讲解.doc_第1页
java_RMI技术讲解.doc_第2页
java_RMI技术讲解.doc_第3页
java_RMI技术讲解.doc_第4页
java_RMI技术讲解.doc_第5页
已阅读5页,还剩11页未读 继续免费阅读

下载本文档

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

文档简介

RMI技术讲解1、 什么是RMI?我们知道远程过程调用(Remote Procedure Call, RPC)可以用于一个进程调用另一个进程(很可能在另一个远程主机上)中的过程,从而提供了过程的分布能力。Java 的 RMI 则在 RPC 的基础上向前又迈进了一步,即提供分布式 对象间的通讯。RMI(Remote Method Invocation)为远程方法调用,是允许运行在一个Java虚拟机的对象调用运行在另一个Java虚拟机上的对象的方法。这两个虚拟机可以是运行在相同计算机上的不同进程中,也可以是运行在网络上的不同计算机中。2、 RMI的用途?RMI的 用途是为分布式Java应用程序之间的远程通信提供服务,提供分布式服务。目前主要应用时封装在各个J2EE项目框架中,例如Spring,EJB(Spring和EJB均封装了RMI技术)在Spring中实现RMI(具体代码见最后一页)在服务器端定义服务的接口,定义特定的类实现这些接口;在服务器端使用org.springframework.remoting.rmi.RmiServiceExporter类来注册服务;在客户端使用org.springframework.remoting.rmi.RmiProxyFactoryBean来实现远程服务的代理功能;在客户端定义访问与服务器端服务接口相同的类3、 RMI的局限?RMI目前使用Java远程消息交换协议JRMP(Java Remote Messaging Protocol)进行通信。JRMP是专为Java的远程对象制定的协议,由于JRMP是专为Java对象制定的,因此,RMI对于用非Java语言开发的应用系统的支持不足。不能与用非Java语言书写的对象进行通信(意思是只支持客户端和服务器端都是Java程序的代码的远程调用)。4、 RMI的使用局限?由于客户机和服务器都是使用Java编写的,二者平台兼容性的要求仅仅是双方都运行在版本兼容的Java虚拟机上。5、 RMI应用程序的基本模型 RMI 本地对象本地对象本地对象客户端程序远程对象远程对象服务器端程序 6、 RMI调用远程方法的参数和返回值当调用远程对象上的方法时,客户机除了可以将原始类型的数据作为参数一外,还可以将对象作为参数来传递,与之相对应的是返回值,可以返回原始类型或对象,这些都是通过Java的对象序列化(serialization)技术来实现的。(换而言之:参数或者返回值如果是对象的话必须实现Serializable接口)7、 RMI体系结构客户机服务器 Stub stbSkeletonskelitn 远程引用层远程引用层虚拟连接 传送层传送层 传送层桩/框架(Stub/Skeleton)层:客户端的桩和服务器端的框架;远程引用(remote reference)层:处理远程引用行为传送层(transport):连接的建立和管理,以及远程对象的跟踪8、 RMI类和接口(完成一个简单RMI需要用到的类)。Java.rmi.remote接口java.rmi.server.RemoteObject(抽象类)Java.rmi.server.RemoteServer(抽象类)Java.rmi.activation.Activatable(抽象类)Java.rmi.server.UnicastRemoteObject java.lang.objectJava.rmi.registry.LocateRegistry(final 类)Java.lang.SecurityManagerJava.rmi.Naming(final类) Java.rmi.RMISecurityManagerjava.io.IOExceptionJava.rmi.RemoteException一、Remote接口:是一个不定义方法的标记接口Public interface Remote在RMI中,远程接口声明了可以从远程Java虚拟机中调用的方法集。远程接口不需满足下列要求:1、 远程接口必须直接或间接扩展Java.rmi.Remote接口,且必须声明为public,除非客户端于远程接口在同一包中2、 在远程接口中的方法在声明时,除了要抛出与应用程序有关的一场之外,还必须包括RemoteException(或它的超类,IOExcepion或Exception)异常3、 在远程方法声明中,作为参数或返回值声明的远程对象必须声明为远程接口,而非该接口的实现类。二、RemoteObject抽象类实现了Remote接口和序列化Serializable接口,它和它的子类提供RMI服务器函数说一点:提供了创建远程对象并将其导出(也就是使他们能够被远程客户机所调用),所需的方法有类UnicastRemoteObject和Activatable提供。子类可以识别远程对象引用的语义,例如服务器是简单的远程对象还是科技获得远程对象三、LocateRegistry final类用于获得特定主机的引导远程对象注册服务器程序的引用(即创建stub),或者创建能在特定端口接收调用的远程对象注册服务程序服务器端:向其他客户机提供远程对象服务SomeService servcie=;/远程对象服务Registry registry=LocateRegisty.getRegistry();/Registry是个接口,他继承了Remote,此方法返回本地主机在默认注册表端口 1099 上对远程对象 Registry 的引用。(还有getRegistry(intport) 返回本地主机在指定 port 上对远程对象 Registry 的引用; getRegistry(Stringhost) 返回指定 host 在默认注册表端口 1099 上对远程对象 Registry 的引用; getRegistry(Stringhost, intport) 返回指定的 host 和 port 上对远程对象 Registry 的引用)registry.bind(“I serve”,service);/ bind(Stringname,Remoteobj) 绑定对此注册表中指定 name 的远程引用。name : 与该远程引用相关的名称 obj : 对远程对象(通常是一个 stub)的引用 还有一些unbind(String name)移除注册表中指定name的绑定。rebind(Stringname,Remoteobj)重新绑定,如果name已存在,但是Remote不一样则替换,如果Remote一样则丢弃现有的绑定lookup(Stringname) 返回注册表中绑定到指定 name 的远程引用,返回RemoteString list() 返回在此注册表中绑定的名称的数组。该数组将包含一个此注册表中调用此方法时绑定的名称快照。客户机端:向服务器提供相应的服务请求。Registry registry=LocateRegisty.getRegistry();SomeService servcie=(SomeService)registry.lookup(“I serve”);Servcie.requestService();四、Naming类和Registry类类似。其中客户端:Naming.lookup(String url)url 格式如下rmi:/localhost/+远程对象引用服务器端:Registry registry=LocateRegistry.createRegistry(int port);Naming.rebind(“service”,service);五、RMISecurityManager类在RMI引用程序中,如果没有设置安全管理器,则只能从本地类路径加载stub和类,这可以确保应用程序不受由远程方法调用所下载的代码侵害。在从远程主机下载代码之前必须执行以下代码来安装RMISecurityManager:System.setSecurityManager(new RMISecurityManager();具体步骤:1、 服务器和客户端必须定义一个能够访问的接口,该接口声明能够远程调用的方法,创建接口继承Remote接口(接口中声明需要调用的远程方法(需要抛出异常)2、 做一个实现类 实现上面创建的接口3、 写服务器端Java程序,注册远程对象。4、 些客户端,获得远程对象的注册表5、 生成stub和skeleton。代码:1 package src;import java.rmi.*;public interface RMIInterface extends Remotepublic java.util.Date getDate()throws RemoteException;2 package src;import java.rmi.*;import java.rmi.server.*;import java.util.Date;public class RMIImplementation extends UnicastRemoteObject implements RMIInterface public RMIImplementation()throws RemoteExceptionsuper();public Date getDate() throws RemoteException / TODO Auto-generated method stubreturn new java.util.Date();3package src;import java.rmi.server.*;import java.rmi.*;public class RMIClient public static void main(String args)if(System.getSecurityManager()=null)System.setSecurityManager(new RMISecurityManager();String url=rmi:/localhost/;tryRMIInterface c=(RMIInterface)Naming.lookup(url+theRemote);System.out.println(服务器大unde系统时间是+c.getDate();catch(Exception e)System.out.println(Error:+e);System.exit(0);4package src;import java.rmi.*;import java.rmi.registry.LocateRegistry;public class RMIServer public static void main(String args)if(System.getSecurityManager()=null)System.setSecurityManager(new RMISecurityManager();tryRMIImplementation theRemote=new RMIImplementation();LocateRegistry.createRegistry(1099);Naming.rebind(theRemote,theRemote);System.out.println(n远程对象窗口,RMI服务器正在运行);catch(Exception e)System.out.println(Error:+e);Spring实现RMI(1)服务器端服务接口Package com.open.rmi.ex2;public interface PerfectTimeI /提供当前时间的服务接口public long getPerfectTime(); 实现服务器端服务接口的类package com.open.rmi.ex2;public class PerfectTime implements PerfectTimeI public long getPerfectTime() return System.currentTimeMillis();(2)在applicationContext中注册服务(3)在客户端的applicationContext中实现远程服务的代理功能(4)在客户端定义访问与服务器端服务接口相同的类package com.open.rmi.ex2;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class TestServer public static void main(String args) ApplicationContext ctx = new ClassPathXmlApplicationContext(applicationContext.xml);DisplayPerfectTime test = (DisplayPerfectTime)ctx.getBean(test);test.display();在applicationContext中的配置首先开发人员应该清楚的是,Java RMI技术是伴随着分布式处理的需求而诞生出来,虽然从RMI的字面翻译没有看出来。在这一点上DCOM(Distributed Object Component Model,分布式对象组件模型,RPC就是通过DCOM机制来实现)似乎表现得更直白一些。分布式处理的构架就决定了无论是RMI还是RPC都至少是C/S模型,即Server作为对象(远程对象或者COM对象)提供者,而Client端作为使用者。所以从出发点上,如果具有一定Windows开发经验的话,我们就不应该把Java RMI技术看得比较晦涩难懂。 同样的,RMI也像DCOM一样,Server端需要先注册服务,而Client端调用远程方法之前需要查找已经注册的服务,由此获得通信端口和传递参数等后续工作。所以,如果开发人员熟悉DCOM机制和RPC开发的话,那么就已经可以大致上知道Java RMI是如何开展工作了。 不同的是,Java平台与生俱来的安全性和良好的扩展性就决定了Java RMI比RPC更加安全和灵活,例如Java RMI可以穿透防火墙,而DCOM机制则不能;Java RMI可以支持嵌入更高级的连接应用,例如结合JNDI,XML技术等,而DCOM机制只有望洋兴叹,从而MS逐步转入到了.NET模型。 以下笔者将从大家都比较熟悉的DCOM机制的目标着手,通过RMI来实现分布式处理,来将读者逐步引入到RMI技术的应用深处。 2 部署框架 实际应用中,我们可以将RMI部署为2层到多层应用。本实例中,我们将RMI部署为3层:客户层应用层后台。按照设计模块将RMI部署划分为4个包:Client(客户端),Check(检查,调试),Application(应用层,RMI服务端)和Server(后台服务端,例如:数据库服务器,文件目录服务器等)。以下是各层和包的内容划分: 图1:RMI部署框架示意图 对于上述框架,请注意以下3个容易忽视的点:(1)客户端和服务器必须同步共享远程接口定义和存根,特别是客户端和服务器端在不同主机的情形下,必须将更新后的远程接口定义和存根同时分发到客户端和服务器端。(2)当客户端和服务器端在不同主机时要考虑部署策略文件(安全因素)。(3)任何时候都不要考虑将过多的“权力”下放给客户端,而是尽可能将业务逻辑地放在应用层。这个问题往往产生在为了方便客户端使用服务端的资源。摘要:随着网络技术、面向对象技术(OOT)的成熟,分布计算技术不再是试验室里的高新技术,分布计算已成为软件设计的主流技术。纯面向对象编程语言Java使分布计算更容易实现。本文介绍先阐述如何判断一个系统是不是分布式系统?并分析在分布计算中,Socket通信协议和RPC的不足,然后论述如何使用Java RMI实现分布计算。 关键字:RMI 分布计算 RPC 1、 引言 分布计算是计算机界由来已久的话题,但过去大多数分布计算应用是专有的,适用范围很窄。随着网络技术飞速发展,对象技术的成熟,现在,分布计算具有跨越网络透明访问异构网络信息资源并进行处理的能力,使它成为新一代计算技术的主流。 Java语言的跨平台性、可移植性使它能够支持网络应用程序的设计。同时JAVA语言提供的远程方法调用(Remote Method Invocation,RMI)特性,使客户机上的程序可以调用服务器上的远程对象,这样就使程序员能够很容易编写出分布计算程序,并在网络环境下进行分布计算。 2、 分布计算及Socket和RPC存在的问题 计算机网络的出现和网络技术的迅速发展,使得原先在物理位置上分散的各种微机、工作站和服务器等计算资源可以通过网络实现互联和交互,协同完成大规模、复杂的计算任务。而Intranet/Internet技术的发展,使软件工程学科出现了一个新的领域?基于网络的分布计算。 分布计算是一个发展迅速的领域,与传统的集中式计算相比,分布计算具有以下优点: 分布计算包含更多计算单元的协同服务; 分布计算具有更好性价比; 分布计算具有更好的可靠性和可用性; 分布计算具有更好的透明性; 分布计算具有更好开放性和可伸缩性; 但关于分布计算定义,还没有形成一个统一的意见。文献1给以关于分布式系统的定义:“分布式系统是基于网络互相连接的若干计算单元系统协同计算的软件实现。”并且给出一个分布系统应该具有的若干属性: 任意数目的分布计算单元(PE),每个PE称之为物理资源。 任意数目的进程,每个进程称之为逻辑单元。 进程之间通过消息传递进行通信。 进程之间以协作的方式交互。 通信延迟不可忽略。 任何单个逻辑或物理的资源故障不会导致整个系统的崩溃。 在资源故障的情况下系统必须具有重新配置和处理故障的能力。 我们可以根据以上定义的属性,来判断一个系统是不是分布计算系统。 分布式系统可以看成彼此不共享内存的网络计算机协同完成多处理机任务,这就意味着分布系统即可以看作为服务器,也可以看作为客户机。因此,文献2提出的分布式系统的定义是:“分布式系统由一系列的节点组成,这些节点在需的时候会根据其定义的接口向其他节点提供服务。”同样在文献3中也给出不同定义。由这些定义我们可以这样认为:分布计算是利用分布在网络的各种信息资源和在网络上动态配置的多台计算机进行信息处理的过程,它是通过基于网络的分布式系统来实现的。 分布式系统中,要求分布在不同节点上对象能够互相通信。而通信基本机制就是:Socket协议通信。Socket协议使用层协议对交换的消息进行编码和解码,因而使用Socket进行设计比较复杂而且容易出错。在面向过程的语言中取代Socket的是远程过程调用RPC(Remote Procedure Call), 而RPC采用中性语言实现,并且返回的是用外部数据表示的值,对数据表示协议依赖很强,很难应用到面向对象分布计算系统中。而远程调用方法RMI(Remote Method Invocation)实质上模拟了应用在分布计算系统中的RPC,使用Java远程信息交换协议JRMP(Java Remote Messaging Protocol)进行通信,而JRMP是专为Java的远程对象通信制定的协议。因此,RMI就具有Java的可移植性,是分布应用的纯Java解决方案,更具有面向对象的特征。 3、 用Java RMI进行分布计算 RMI的实现主要基于以下三层来完成,如图所示。 Stub&skeleton层:这是RMI应用层与其他部分的接口,它传输给远程引用层的数据是从调度流中提取而来。调度流使用对象序列化机制实现的,通过这个机制,Java对象可以在地址空间进行传递。Stub是客户端的代理,它实现了所有远程对象的接口;Skeleton是服务器端的实体,它包括了一个被具体远程对象所支持的接口。 远程引用层:主要处理低端传输接口,也负责执行专门的远程引用协议,这个协议是独立于客户端的stub和服务端的skeleton之外的。 传输层:实现具体的客户端到服务器端的网络连接。主要执行以下动作:建立远程地址空间的连接;对连接进行管理和监控连接状态;监听新的调用;建立并维护地址空间的远程对象表;建立新调用的连接;定位远程调用的调度程序,并建立与此调度程序的连接。 而在Java语言中,RMI是一种Java虚拟机之间对象相互调用对方的函数,也是启动对方进程的一种机制,主要使用Java.rmi和Java.rmi.Server包中定义的接口和类。使用Java RMI开发分布计算程序流程如下图所示: (1)定义远程类的接口:服务器对象必须通过远程接口声明服务; (2)实现远程接口:必须提供一个Java服务器类,给类实现你向外部世界公布的接 (3)编译服务器:必须用javac编译服务器类; (4)运行存根编译器:RMI提供一个成为rmic的存根编译器,对.class文件运行rmic;(5)启动RMIreGIStry; (6)启动服务方应用程序; (7)使用RMI注册表注册所有远程对象实例,使客户可以达到他们; (8)编写客户端代码:必须使用java.rmi.Naming类定位远程对象,然后通过做远程对象代理的存根来调用方法; (9)编译客户端代码; (10)启动客户。 4、用Java RMI实现分布计算 笔者曾用Java RMI技术实现复杂矩阵乘法问题以及精确计算圆周率小数点后n位(当n很大时)的问题,这里限于篇幅仅给出复杂矩阵乘法程序的部分代码: 定义远程接口 import java.rmi.*; public interface MatrixInt extends Remote/继承Remote接口 public static void Multiply(int MatricX,int MatrixY,int MatrixZ) throws RemoteException; public static void OutputMatric(int Matrix)throws RemoteException; 编写远程服务器上实现接口的方法 import java.rmi.server.*; public class MatrixXY extends UnicastRemoteObject implements MatrixInt public MatrixXY () throws java.rmi.RemoteExceptionsuper(); public static void Multiply(int MatrixX,int MatrixY,int MatrixZ)/矩阵相乘方法 public static void OutputMatrix(int Matrix) 创建远程服务器实现接口方法的对象 import java.rmi.*; public class Server public static void main(String args) new Server(); tryMatrixInt c=new MatrixXY();Naming.rebind(rmi:/loacalhost:1099/Service,c); catch(Exception e)System.out.println(Error+ e); 客户端程序代码 import java.rmi.*; import java.rmi.server.*; public class client public static void main(String args) int MatrixX=1,4,5,3,5,8,9,13,7;int MatrixY=5,7,9,6,2,7,2,5,7; int MatrixZ=new int33; tryMatrixInt c=(MatrixInt)Naming.loopup(“rmi:/remotehost/service”); c.Mutiply(MatrixX,MatrixY,MatrixZ); System.out.println(“The result is /n“);c.OutputMatrix(MatrixZ); catch(Exception e)System.out.println(“error”+e); 5、结束语 Java RMI是解决分布计算方案之一,它能开发出可移植,功能强大的分布计算程序。但Java RMI不能用于与非Java语言开发的对象进行通信,这正是它的不足之处,但可以借助CORBA与其它语言书写的对象进行通信,这也是分布计算领域研究的热点问题之一。 The Application of Distribution Based on Java RIM PengTao ZhaoPengWei (ShenYang Normal University IT College 110034) With the maturity of object-oriented technology, distributed computing technology has walked out the laboratory and become mainstream in software design.The pure object-oriented computing Java makes distributed computing more easy.In this article at first we introduce how to judge if system is distributed computing system or not and analyze defect the defect of Socket and RPC,then we demonstrate how Java RMI works. Key word: RMI distributed computing RPCJava RMI (Remote Method Invocation 远程方法调用)是用Java 在JDK1.1 中实现的,它大大增强了Java 开发 分布式应用的能力。 Java 作为一种风靡一时的网络开发语言,其巨大的威力就体现在它强大的开发分布式网络应用的能力上,而RMI就是开发百分之百纯 Java 的网络分布式应用系统的核心解决方案之一。 其实它可以被看作是RPC 的Java 版本。但是传统RPC 并不能很好地应用于分布式对象系统。而 Java RMI 则支持存储于不同地址空间的程序级对象之间彼此进行通信,实现远程对象之间的无缝远程调用。 RMI 目前使用Java 远程消息交换协议 JRMP(Java Remote Messaging Protocol )进行通信。JRMP 是专为Java 的远程对象制定的协议。因 此,Java RMI 具有Java 的Write Once,Run Anywhere 的优点,是分布式应用系统的百分之百纯Java 解决方案。 用 Java RMI 开发的应用系统可以部署在任何支持JRE (Java Run Environment Java ,运行环境)的平台上。但由于JRMP 是 专为Java 对象制定的,因此,RMI 对于用非Java 语言开发的应用系统的支持不足。不能与用非Java 语言书写的对象进行通信。本文拟从程序的角度举 例介绍怎样利用RMI实现Java 分布式应用。 一、RMI系统运行机理 RMI应用程序通常包括两个独立的程序:服务器程序和客户机程序。 典型的服务器应用程序将创建多个远程对象,使这些远程对象能够被引用,然后等待 客户机调用这些远程对象的方法。 而典型的客户机程序则从服务器中得到一个或多个远程对象的引用,然后调用远程对象的方法。RMI为服务器和客户机进行通信 和信息传递提供了一种机制。 在与远程对象的通信过程中,RMI 使用标准机制:stub 和skeleton 。 远程对象的stub 担当远程对象的客户本地代表或代理人角色。 调用 程序将调用本地stub 的方法,而本地stub 将负责执行对远程对象的方法调用。在RMI 中,远程对象的stub 与该远程对象所实现的远程接口集相同。 调 用stub 的方法时将执行下列操作:Java代码 (1) 初始化与包含远程对象的远程虚拟机的连接; (2) 对远程虚拟机的参数进行编组(写入并传输); (3) 等待方法调用结果; (4) 解编(读取)返回值或返回的异常; (5) 将值返回给调用程序。 为了向调用程序展示比较简单的调用机制,stub将参数的序列化和 网络级通信等细节隐藏了起来。在远程虚拟机中,每个远程对象都可以有相应的skeleton(在JDK1.2环境中无需使用skeleton)。 Skeleton负责将调用分配给实际的远程对象实现。 它在接收方法调用时执行下列操作:Java代码 (1) 解编(读取)远程方法的参数; (2) 调用实际远程对象实现上的方法; (3) 将结果(返回值或异常)编组(写入并传输)给调用程序。 stub和skeleton由rmic编译器生成。利用RMI编写分布式对象应用程序需要完成以下工作:Java代码 (1) 定位远程对象。应用程序可使用两种机制中的一种得到对远程对象的引用。 它既可用 RMI的简单命名工具rmiregistry来注册它的远程对象, 也可以将远程对象引用作为常规操作的一部分来进行传递和返回。 (2)与远程对象通信。远程对象间通信的细节由RMI处理,对于程序员来说, 远程通信看起来就像标准的Java方法调用。 (3)给作为参数或返回值传递的对象加载类字节码。 因为 RMI允许调用程序将纯Java对象传给远程对象,所以,RMI将提供必要的机制,既可以加载对象的代码又可以传输对象的数据。在RMI分布式应用程序运 行时,服务器调用注册服务程序以使名字与远程对象相关联。客户机在服务器上的注册服务程序中用远程对象的名字查找该远程对象

温馨提示

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

最新文档

评论

0/150

提交评论