资源预览内容
第1页 / 共19页
第2页 / 共19页
第3页 / 共19页
第4页 / 共19页
第5页 / 共19页
第6页 / 共19页
第7页 / 共19页
第8页 / 共19页
第9页 / 共19页
第10页 / 共19页
亲,该文档总共19页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
228 第七章第七章 远程对象远程对象 ? 远程方法调用 ? 安装 RMI(Remote Method Invocation) ? Java 和 CORBA 分布式对象技术主要是在分布式异构环境下建立应用系统框架和对象构件。 在应用系统 框架的支撑下, 开发者可以将软件功能封装为更易管理和使用的对象, 这些对象可以跨越不 同的软、硬件平台进行互操作。目前,分布式互操作标准主要有 Microsoft 的 COM/DCOM 标准、Sun 公司的 Java RMI 标准和 OMG 组织的 CORBA 标准。 本章将解释那些使对象间通信成为可能的模型, 解释分布式对象能发挥作用的情况。 展 示怎样使用远程对象以及在两个 Java 虚拟机问进行通信的远程方法调用(remote method invocation,RMI)(它可以在不同的计算机上运行)。介绍公用对象请求代理结构(Common Object Request Broker Architecture,CORBA),它允许使用不同语言(Java 编程语言、C+ 等)编写的对象进行通信。 7.1 远程方法调用远程方法调用 7.1.1 远程方法体系结构远程方法体系结构 远程方法调用机制 RMI 是构成 Java 分布对象模型的基础结构。RMI 系统包括框架层、 远程引用层和传输层。目前,RMI 的传输层是基于 TCP 实现的,将来的 RMI 体系结构建立在 IIOP 协议之上, 可以实现 Java 技术与 CORBA 技术的深层融合。 应用层建立在 RMI 系统之上。 下图给出了各层之间的关系。 RMI 客户 RMI 服务接口RMI 服务器 RMI 服务存根RMI 骨架 远程引用层 传输层(一般是 TCP) Internet Protocol (IP) 图 7- 1 远程方法调用体系结构 7.1.2 远程方法调用实例远程方法调用实例 RMI(Remote Method Invocation)是 Java 引入的分布式对象软件包,它的出现简化 了在多台机器上的 Java 应用之间的通信。 要使用 RMI,必须构建四个主要的类:远程对象的本地接口、远程对象实现、RMI 客 户机和 RMI 服务器。 RMI 服务器生成远程对象实现的一个实例, 并用一个专有的 URL 注册。 RMI 客户机在远程 RMI 服务器上查找服务对象,并将它转换成本地接口类型,然后像对待 一个本地对象一样使用它。 229 见表 7-1,RMI 遵循一定的命名规则。 表 7- 1 RMI 类的命名规则 无后缀(例如,Greater) 远程接口 Impl 后缀(比如,GreaterImpl) 实现接口的服务器类 Server 后缀(比如,GreaterServer) 创建服务器对象的服务器程序 Client 后缀(比如,GreatingClient) 调用远程方法的客户程序 _Stub 后缀(比如,GreaterImpl_Stub) rmic 程序自动生成的代码存根类 _Skel 后缀(比如, GreaterImpl_Skeleton)rmic 程序自动生成的框架类 本例中, 远程对象的本地接口是 Greater, 它只有一个方法 public String getMessage()。 远程对象的实现是GreaterImpl, RMI客户机是GreatingClient, RMI服务器是GreateServer。 下面是一个简单的 RMI 例子,远程对象只返回一个消息字符串。要使这个例子更有价 值,我们需要做的就是完善远程对象实现类。 1) 远程对象的本地接口类(Greater.java) 该类仅仅是一个接口,而不是实现,RMI 客户机可以直接使用它,RMI 服务器必须通 过一个远程对象来实现它,并用某个 URL 注册它的一个实例。 Greater.java import java.rmi.*; public interface Greater extends Remote public String getMessage() throws RemoteException; 本地接口(Greater)必须是公共的,否则客户机在加载一个实现该接口的远程对象时 就会出错。此外,它还必须从 java.rmi.Remote 继承而来,接口中的每一个方法都必须抛出 远程异常 java.rmi.RemoteException。 这个接口扩展了另一个接口 java.rmi.Remoto。Remoto 接口告诉 RMI:如果一个类直 接或者通过继承实现了这个接口,那么它就是可以远程访问的。 2) RMI 客户类(GreatingClient.java) RMI 客户使用 Naming.lookup 在指定的远程主机上查找对象,若找到就把它转换成本 地接口 Greater 类型,然后像一个本地对象一样使用它。与 CORBA 不同之处在于 RMI 客 户必须知道提供远程服务主机的 URL,这个 URL 可以通 过 rmi:/host/path 或 rmi:/host:port/path 来指定,如果省略端口号,就使用 1099。Naming.lookup 可能产生三个 异常:RemoteException、NotBoundException、MalformedURLException,三个寻常都需 要捕获。RemoteException、Naming 和 NotBoundException 在 java.rmi.*中定义, MalformedURLException 在 java.net.*中定义。另外,客户机将向远程对象传递串行化对象 Serializable,所以还应在程序中输入 java.io.*。 GreatingClient.java import java.rmi.*; import java.net.*; import java.io.*; public class GreatingClient public static void main(String args) try /通过URL在远程主机上查找对象,并把它转化为本地接口Greater类型 230 Greater greater = (Greater) Naming.lookup (“rmi:/localhost:1099/GreaterService“); System.out.println(greater.getMessage(); /调用远程对象的方法 catch(RemoteException re) System.out.println(“RemoteException: “ + re); catch(NotBoundException nbe) System.out.println(“NotBoundException: “ + nbe); catch(MalformedURLException mfe)System.out.println(“MalformedURLException:“ + mfe); 这个类希望与一个称为 GreetingServer 的服务器进行通信。 3) 远程对象实现类(GreaterImpl.java) 这个类真正实现 RMI 客户调用的远程对象,它必须从 UnicastRemoteObject 继承,其 构造函数应抛出 RemoteException 异常。 GreaterImpl.java import java.rmi.*; import java.rmi.server.UnicastRemoteObject; public class GreaterImpl extends UnicastRemoteObject implements Greater public GreaterImpl() throws RemoteException /构造函数抛出RemoteException public String getMessage() throws RemoteException return(“Here is a remote message.“); /向 RMI 客户返回一个消息串 GreeterImpl实 现 了Greeter , 但 是 它 还 扩 展 了UnicastRemoteObject 。 UnicastRemoteObject派生自java.rmi.server.RemoteServer和 java.rmi.server.RemoteObject 类。 它支持在客户和已经激活的服务器之间进行点对点通信。 它支持调用方法、传递参数和返回结果。它是为程序员提供的方便措施,以便使它们不必实 现有效的 toString()、equals()、hashCode()方法(RMI 要求覆盖这些方法)。 4) RMI 服务器类(GreaterServer.java) 该类创建远程对象实现 GreaterImpl 的一个实例,然后用一个特定的 URL 来注册它, 所谓注册就是通过 Naming.bind 或 Naming.rebind 来将 GreaterImpl 实例绑定到 URL 上。 GreaterServer.java import java.rmi.*; import java.net.*; public class GreaterServer public static void main(String args) try GreaterImpl localObject = new GreaterImpl(); /生成远程对象实现的一个实例 /将远程对象实例绑定到服务器上 Naming.rebind(“rmi:/localhost:1099/GreaterService“, localObject); catch(RemoteException re)System.out.println(“RemoteException:“+re); 231 catch(MalformedURLException mfe) System.out.println(“MalformedURLException: “+mfe); GreeterServer 为服务命名并且使用这个名称注册 GreeterImpl 类对象。这是通过对命 令服务执行 rebind()方法来完成的。在它的 main()方法中对服务器进行实例化。我们在这里 使 用rebind() 调 用 是 因 为 如 果 注 册 表 中 已 经 存 在 这 个 名 称 , 它 不 会 抛 出 AlreadyBoundException。 下面对以上程序进行编译和运行 1) 编译 RMI 客户和服务器,这将自动编译远程对象的本地接口和远程对象实现: 图 7- 2 编译 RMI 客户和服务器 编译 GreatingClient.java 时,会自动编译远程对象的本地接口 Greater.java。 编译 GreaterServer.java 时,会自动编译远程对象实现 GreaterImpl.java。 2) 生成客户模块和服务器框架 现需要为 GreaterImpl 类生成代码存根。存根用于调度(加密和发送)参数和方法调用的 结果,程序员不直接使用这些类。而且它们无须手工开发,rmic 工具自动生成这种类。 图 7- 3 生成客户承接模块和服务器框架 这将构造 GreaterImpl_Stub.class 和 GreaterImpl_Skeleton.class。 现将 Greater.class、 GreatingClient.class 和 GreaterImpl_Stub.class 拷贝到 RMI 客户机,将 Greater.class、
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号