EJB技术的基础是另外两种技术:RMI-IIOP和JNDI。要想了解EJB,一定要先了解RMI-IIOP和JNDI。因此,我们在介绍EJB细节之前,先了解这两项技术。我们的介绍比较基本,因此大多数组织只要了解这些就已经够了。
EJB技术的基础是另外两种技术:RMI-IIOP和JNDI。要想了解EJB,一定要先了解RMI-IIOP和JNDI。因此,我们在介绍EJB细节之前,先了解这两项技术。我们的介绍比较基本,因此大多数组织只要了解这些就已经够了。
Java RMI-IIOP Java RMI-IIOP(Java Remote Method Invocation over the Internet Inter-ORB Protocol)是J2EE的网络机制。Java RMI-IIOP允许你编写分布式对象,使得对象的通信范围能够在内存中,跨Java虚拟机,跨物理设备。
Remote Method Invocation RPC(remote procedure call)是一台机器的进程调用另一台机器的进程的过程。而remote method invocation则比RPC的概念更进一步,允许分布式对象间的通信。RMI-IIOP允许调用远程对象的方法,而不仅仅是过程。这有利于面向对象编程。Java RMI (Remote Method Invocation 远程方法调用)是用Java在JDK1.1中实现的,它大大增强了Java开发分布式应用的能力。Java作为一种风靡一时的网络开发语言,其巨大的威力就体现在它强大的开发分布式网络应用的能力上,而RMI就是开发百分之百纯Java的网络分布式应用系统的核心解决方案之一。其实它可以被看作是RPC的Java版本。但是传统RPC并不能很好地应用于分布式对象系统。而Java RMI 则支持存储于不同地址空间的程序级对象之间彼此进行通信,实现远程对象之间的无缝远程调用。
remote method invocation决不简单,需要考虑几个问题:
marshalling和unmarshalling.在不同机器间通过网络传递变量(包括Java基本类型和对象),如果目标机器表示数据的方式和原机器不同该怎么办?例如二进制库不同。因此marshalling和unmarshalling就是传递变量的过程。
变量传递方法.变量有两种传递方法:pass-by-value和pass-by-reference。对于前者,你的目标方法只需使用一份copy,但对于后者,远程方法对变量的任何修改都会影响到源数据。
网络和机器的不稳定.需要有一种机制保证一个JVM崩溃之后,不会影响系统的正常运作。
在 Java 分布式对象模型中,remote object 是这样一种对象:它的方法可以从其它 Java 虚拟机(可能在不同的主机上)中调用。该类型的对象由一种或多种 remote interfaces(它是声明远程对象方法的 Java 接口)描述。远程方法调用 (RMI) 就是调用远程对象上远程接口的方法的动作。更为重要的是,远程对象的方法调用与本地对象的方法调用语法相同。
Remote Interface RMI-IIOP遵循了接口和实现的原则。你写的所有网络代码都是应用于接口,而不是实现。实际上,你必须使用RMI-IIOP中的范例,没有其它的选择。直接在你的对象实现上执行远程调用是不可能的,你只能在对象类的接口上单独进行这一操作。
所以我们在使用RMI-IIOP时,你必须建立一个客户接口,叫做remote interface。这个远程接口应该扩展java.rmi.Remote接口。
Remote Object Implementation
远程对象和客户机的物理位置并不是很重要。可以运行在同一地址空间或是跨Internet运行。
为了使对象成为一个远程对象,你需要执行一下步骤:
继承javax.rmi.PortableRemoteObject。PortableRemoteObject是进行远程调用的基类,当你的远程对象调用构造器时,PortableRemoteObject对象的构造器也会自动被调用。
不继承javax.rmi.PortableRemoteObject。如果你的远程对象需要继承其它的类,而Java不允许多重继承,因此你不能继承PortableRemoteObject。这时,你需要手动调用javax.rmi.PortableRemoteObject.exportObject()。
Stub和Skeletons 我们来看看在RMI-IIOP背后隐藏的网络架构。RMI-IIOP的一个好处就是你可以不用管你要调用的对象是本地的还是远程的。这就叫做local/remote transparency。
RMI应用程序通常包括两个独立的程序:服务器程序和客户机程序。典型的服务器应用程序将创建多个远程对象,使这些远程对象能够被引用,然后等待客户机调用这些远程对象的方法。而典型的客户机程序则从服务器中得到一个或多个远程对象的引用,然后调用远程对象的方法。RMI为服务器和客户机进行通信和信息传递提供了一种机制。
在与远程对象的通信过程中,RMI使用标准机制:stub和skeleton。远程对象的stub担当远程对象的客户本地代表或代理人角色。调用程序将调用本地stub的方法,而本地stub将负责执行对远程对象的方法调用。在RMI中,远程对象的stub与该远程对象所实现的远程接口集相同。调用stub的方法时将执行下列操作:(1) 初始化与包含远程对象的远程虚拟机的连接;(2) 对远程虚拟机的参数进行编组(写入并传输);(3) 等待方法调用结果;(4) 解编(读取)返回值或返回的异常;(5) 将值返回给调用程序。为了向调用程序展示比较简单的调用机制,stub将参数的序列化和网络级通信等细节隐藏了起来。在远程虚拟机中,每个远程对象都可以有相应的skeleton(在JDK1.2环境中无需使用skeleton)。Skeleton负责将调用分配给实际的远程对象实现。它在接收方法调用时执行下列操作:(1) 解编(读取)远程方法的参数;(2) 调用实际远程对象实现上的方法;(3) 将结果(返回值或异常)编组(写入并传输)给调用程序。stub和skeleton由rmic编译器生成。
要实现local/remote transparency可没有那么简单。为了屏蔽你调用的是远端主机上的对象,RMI-IIOP需要模拟一个本地对象供你调用。这个本地对象叫做stub。它负责接受本地的方法调用请求,把这些请求委托给真正实现它们的对象(可以通过网络定位)。这样就使得远程调用看起来就和本地调用一样。
利用RMI编写分布式对象应用程序需要完成以下工作:(1) 定位远程对象。应用程序可使用两种机制中的一种得到对远程对象的引用。它既可用RMI的简单命名工具rmiregistry来注册它的远程对象,也可以将远程对象引用作为常规操作的一部分来进行传递和返回。(2)与远程对象通信。远程对象间通信的细节由RMI处理,对于程序员来说,远程通信看起来就像标准的Java方法调用。(3)给作为参数或返回值传递的对象加载类字节码。因为RMI允许调用程序将纯Java对象传给远程对象,所以,RMI将提供必要的机制,既可以加载对象的代码又可以传输对象的数据。在RMI分布式应用程序运行时,服务器调用注册服务程序以使名字与远程对象相关联。客户机在服务器上的注册服务程序中用远程对象的名字查找该远程对象,然后调用它的方法。
定位远程对象。应用程序可使用两种机制中的一种得到对远程对象的引用。它既可用 RMI 的简单命名工具 rmiregistry 来注册它的远程对象;也可将远程对象引用作为常规操作的一部分来进行传递和返回。
与远程对象通讯。远程对象间通讯的细节由 RMI 处理;对于程序员来说,远程通讯看起来就象标准的 Java 方法调用。给作为参数或返回值传递的对象加载类字节码因为 RMI允许调用程序将纯 Java 对象传给远程对象,所以 RMI 将提供必要的机制,既可以加载对象的代码又可以传输对象的数据。服务器调用注册服务程序以使名字与远程对象相关联。客户机在服务器注册服务程序中用远程对象的名字查找该远程对象,然后调用它的方法。RMI 能用 Java系统支持的任何 URL 协议(例如 HTTP、FTP、file 等)加载类字节码。
stub只是解决了一半的问题。我们还希望远程对象也不用考虑网络问题。因此远程对象也需要一个本地的skeleton来接受调用。skeleton接受网络调用并把调用委托给远程对象实现。
你的J2EE服务器应当提供一种方法来产生必须的stub和skeleton,以减轻你的对网络问题考虑的负担。典型的是通过命令行工具来完成,例如sun的J2EE参考实现包就使用了一个名为rmic(RMI compiler)的工具来产生stub和skeleton类。你应当把stub部署在客户机上,并把skeleton部署在服务器上。
对象序列化和变量传递 在RMI分布式应用系统中,服务器与客户机之间传递的Java对象必须是可序列化的对象。不可序列化的对象不能在对象流中进行传递。对象序列化扩展了核心Java输入/输出类,同时也支持对象。对象序列化支持把对象编码以及将通过它们可访问到的对象编码变成字节流;同时,它也支持流中对象图形的互补重构造。序列化用于轻型持久性和借助于套接字或远程方法调用(RMI)进行的通信。序列化中现在包括一个 API(Application Programming Interface,应用程序接口),允许独立于类的域指定对象的序列化数据,并允许使用现有协议将序列化数据域写入流中或从流中读取,以确保与缺省读写机制的兼容性。
为编写应用程序,除多数瞬态应用程序外,都必须具备存储和检索 Java对象的能力。以序列化方式存储和检索对象的关键在于提供重新构造该对象所需的足够对象状态。存储到流的对象可能会支持 Serializable(可序列化)或 Externalizable(可外部化)接口。对于Java对象,序列化形式必须能标识和校验存储其内容的对象所属的 Java类,并且将该内容还原为新的实例。对于可序列化对象,流将提供足够的信息将流的域还原为类的兼容版本。对于可外部化对象,类将全权负责其内容的外部格式。序列化 Java 对象的目的是:提供一种简单但可扩充的机制,以序列化方式维护 Java对象的类型及安全属性;具有支持编组和解编的扩展能力以满足远程对象的需要;具有可扩展性以支持 Java 对象的简单持久性;只有在自定义时,才需对每个类提供序列化自实现;允许对象定义其外部格式。
java.rmi.Remote 接口 在 RMI 中,远程接口是声明了可从远程 Java 虚拟机中调用的方法集。远程接
口必须满足下列要求:
远程接口至少必须直接或间接扩展 jav
查看本文来源