八宝书库 > 文学其他电子书 > Java编程思想第4版[中文版](PDF格式) >

第171部分

Java编程思想第4版[中文版](PDF格式)-第171部分

小说: Java编程思想第4版[中文版](PDF格式) 字数: 每页4000字

按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!




如欲深入了解这个包内包含的类,请参考微软公司的产品文档。  



A。5。5 ActiveX/Beans 集成  



Java/ 集成一个有趣的结果就是ActiveX/Beans 的集成。也就是说,Java Bean 可包含到象 VB或任何一种 

Microsoft Office 产品那样的 ActiveX 容器里。而一个ActiveX 控件可包含到象Sun BeanBox 这样的Beans 

容器里。Microsoft JVM 会帮助我们考虑到所有的细节。一个 ActiveX 控件仅仅是一个 服务器,它展示 

了预先定义好的、请求的接口。Bean 只是一个特殊的Java 类,它遵循特定的编程风格。但在写作本书的时 

候,这一集成仍然不能算作完美。例如,虚拟机不能将JavaBeans 事件映射成为 事件模型。若希望从 

ActiveX 容器内部的一个Bean 里对事件加以控制,Bean 必须通过低级技术拦截象鼠标行动这类的系统事件, 

不能采用标准的JavaBeans 委托事件模型。  

抛开这个问题不管,ActiveX/Beans 集成仍然是非常有趣的。由于牵涉的概念与工具与上面讨论的完全相 

同,所以请参阅您的Microsoft 文档,了解进一步的细节。  



A。5。6  固有方法与程序片的注意事项  



固有方法为我们带来了安全问题的一些考虑。若您的 Java 代码发出对一个固有方法的调用,就相当于将控制 

权传递到了虚拟机“体系”的外面。固有方法拥有对操作系统的完全访问权限!当然,如果由自己编写固有 

方法,这正是我们所希望的。但这对程序片来说却是不可接受的——至少不能默许这样做。我们不想看到从 

因特网远程服务器下载回来的一个程序片自由自在地操作文件系统以及机器的其他敏感区域,除非特别允许 

它这样做。为了用 J/Direct ,RNI 和 集成防止此类情况的发生,只有受到信任(委托)的 Java 代码才有 

权发出对固有方法的调用。根据程序片的具体使用,必须满足不同的条件才可放行。例如,使用 J/Direct 的 

一个程序片必须拥有数字化签名,指出自己受到完全信任。在写作本书的时候,并不是所有这些安全机制都 

已实现(对于Microsoft SDK for Java ,beta 2 版本)。所以当新版本出现以后,请务必留意它的文档说 

明。  



A。6 CORBA   



在大型的分布式应用中,我们的某些要求并非前面讲述的方法能够满足的。举个例子来说,我们可能想同以 

前遗留下来的数据仓库打交道,或者需要从一个服务器对象里获取服务,无论它的物理位置在哪里。在这些 

情况下,都要求某种形式的“远程过程调用” (RPC),而且可能要求与语言无关。此时,CORBA 可为我们提 

供很大的帮助。  

CORBA 并非一种语言特性,而是一种集成技术。它代表着一种具体的规范,各个开发商通过遵守这一规范, 

可设计出符合CORBA 标准的集成产品。CORBA 规范是由OMG 开发出来的。这家非赢利性的机构致力于定义一 

个标准框架,从而实现分布式、与语言无关对象的相互操作。  

利用CORBA,我们可实现对Java 对象以及非 Java 对象的远程调用,并可与传统的系统进行沟通——采用一 

种“位置透明”的形式。Java 增添了连网支持,是一种优秀的“面向对象”程序设计语言,可构建出图形化 

和非图形化的应用(程序)。Java 和OMG 对象模型存在着很好的对应关系;例如,无论 Java 还是CORBA 都 

实现了“接口”的概念,并且都拥有一个引用(参考)对象模型。  



A。6。1 CORBA 基础  



由OMG 制订的对象相互操作规范通常称为“对象管理体系”(ObjectManagement Architecture,OMA)。OMA 

定义了两个组件:“核心对象模型”(Core Object Model)和“OMA 参考体系”(OMA Reference  

Model)。OMA 参考体系定义了一套基层服务结构及机制,实现了对象相互间进行操作的能力。OMA 参考体系 

包括“对象请求代理”(Object Request Broker,ORB)、“对象服务”(Object Services,也称作 



                                                                  666 


…………………………………………………………Page 668……………………………………………………………

CORBAservices )以及一些通用机制。  

ORB 是对象间相互请求的一条通信总线。进行请求时,毋需关心对方的物理位置在哪里。这意味着在客户代 

码中看起来象一次方案调用的过程实际是非常复杂的一次操作。首先,必须存在与服务器对象的一条连接途 

径。而且为了创建一个连接,ORB 必须知道具体实现服务器的代码存放在哪里。建好连接后,必须对方法自 

变量进行“汇集”。例如,将它们转换到一个二进制流里,以便通过网络传送。必须传递的其他信息包括服 

务器的机器名称、服务器进程以及对那个进程内的服务器对象进行标识的信息等等。最后,这些信息通过一 

种低级线路协议传递,信息在服务器那一端解码,最后正式执行调用。ORB 将所有这些复杂的操作都从程序 

员眼前隐藏起来了,并使程序员的工作几乎和与调用本地对象的方法一样简单。  

并没有硬性规定应如何实现ORB 核心,但为了在不同开发商的 ORB 之间实现一种基本的兼容,OMG 定义了一 

系列服务,它们可通过标准接口访问。  

  

1。 CORBA 接口定义语言(IDL)  

CORBA 是面向语言的透明而设计的:一个客户对象可调用属于不同类的服务器对象方法,无论对方是用何种 

语言实现的。当然,客户对象事先必须知道由服务器对象揭示的方法名称及签名。这时便要用到 IDL。CORBA  

IDL是一种与语言无关的设计方法,可用它指定数据类型、属性、操作、接口以及更多的东西。IDL 的语法类 

似于C++或 Java 语法。下面这张表格为大家总结了三种语言一些通用概念,并展示了它们的对应关系。  

  

CORBA IDL Java C++  

  

模块(Module) 包(Package) 命名空间(Namespace)  

接口(Interface) 接口(Interface) 纯抽象类(Pure abstract class)  

方法(Method) 方法(Method) 成员函数(Member function)  

  

继承概念也获得了支持——就象C++那样,同样使用冒号运算符。针对需要由服务器和客户实现和使用的属 

性、方法以及接口,程序员要写出一个 IDL描述。随后,IDL会由一个由厂商提供的 IDL/Java 编译器进行编 

译,后者会读取 IDL源码,并生成相应的Java 代码。  

IDL编译器是一个相当有用的工具:它不仅生成与 IDL等价的 Java 源码,也会生成用于汇集方法自变量的代 

码,并可发出远程调用。我们将这种代码称为“根干”(Stub and Skeleton)代码,它组织成多个Java 源 

文件,而且通常属于同一个Java 包的一部分。  

  

2。 命名服务  

命名服务属于CORBA 基本服务之一。CORBA 对象是通过一个引用访问的。尽管引用信息用我们的眼睛来看没 

什么意义,但可为引用分配由程序员定义的字串名。这一操作叫作“引用的字串化”。一个叫作“命名服 

务”(Naming Service)的OMA 组件专门用于执行“字串到对象”以及“对象到字串”转换及映射。由于命 

名服务扮演了服务器和客户都能查询和操作的一个电话本的角色,所以它作为一个独立的进程运行。创建 

 “对象到字串”映射的过程叫作“绑定一个对象”;删除映射关系的过程叫作“取消绑定”;而让对象引用 

传递一个字串的过程叫作“解析名称”。  

比如在启动的时候,服务器应用可创建一个服务器对象,将对象同命名服务绑定起来,然后等候客户发出请 

求。客户首先获得一个服务器引用,解析出字串名,然后通过引用发出对服务器的调用。  

同样地,“命名服务”规范也属于CORBA 的一部分,但实现它的应用程序是由ORB 厂商(开发商)提供的。 

由于厂商不同,我们访问命名服务的方式也可能有所区别。  



A。6。2  一个例子  



这儿显示的代码可能并不详尽,因为不同的ORB 有不同的方法来访问CORBA 服务,所以无论什么例子都要取 

决于具体的厂商(下例使用了JavaIDL,这是 Sun 公司的一个免费产品。它配套提供了一个简化版本的ORB、 

一个命名服务以及一个“IDL→Java ”编译器)。除此之外,由于 Java 仍处在发展初期,所以在不同的 

Java/CORBA 产品里并不是包含了所有 CORBA 特性。  

我们希望实现一个服务器,令其在一些机器上运行,其他机器能向它查询正确的时间。我们也希望实现一个 

客户,令其请求正确的时间。在这种情况下,我们让两个程序都用Java 实现。但在实际应用中,往往分别采 

用不同的语言。  

  

1。 编写 IDL源码  



                                                                       667 


…………………………………………………………Page 669……………………………………………………………

第一步是为提供的服务编写一个 IDL描述。这通常是由服务器程序员完成的。随后,程序员就可用任何语言 

实现服务器,只需那种语言里存在着一个CORBA IDL 编译器。  

IDL文件已分发给客户端的程序员,并成为两种语言间的桥梁。  

下面这个例子展示了时间服务器的 IDL描述情况:  

  

module RemoteTime {  

   interface ExactTime {  

      string getTime();  

   };  

};  

  

这是对 RemoteTime 命名空间内的 ExactTime 接口的一个声明。该接口由单独一个方法构成,它以字串格式返 

回当前时间。  

  

2。 创建根干  

第二步是编译 IDL,创建Java 根干代码。我们将利用这些代码实现客户和服务器。与JavaIDL 产品配套提供 

的工具是idltojava:  

idltojava …fserver …fclient RemoteTime。idl  

其中两个标记告诉 idltojava 同时为根和干生成代码。idltojava 会生成一个 Java 包,它在 IDL模块、 

RemoteTime 以及生成的Java 文件置入 RemoteTime 子目录后命名。_ExactTimeImplBase。java 代表我们用于 

实现服务器对象的“干”;而_ExactTimeStub。java 将用于客户。在ExactTime。java 中,用Java 方式表示 

了IDL 接口。此外还包含了用到的其他支持文件,例如用于简化访问命名服务的文件。  

  

3。 实现服务器和客户  

大家在下面看到的是服务器端使用的代码。服务器对象是在ExactTimeServer 类里实现的。 

RemoteTimeServer 这个应用的作用是:创建一个服务器对象,通过 ORB 为其注册,指定对象引用时采用的名 

称,然后“安静”地等候客户发出请求。  

  

import RemoteTime。*;  

  

import org。omg。CosNaming。*;  

import org。omg。CosNaming。NamingContextPackage。*;  

import org。omg。CORBA。*;  

  

import java。util。*;  

import java。text。*;  

  

// Server object implementation  

class ExactTimeServer extends _ExactTimeImplBase{  

  public String getTime(){  

    return DateFormat。  

        getTimeInstance(DateFormat。FULL)。  

          format(new Date(  

              System。currentTimeMillis()));  

  }  

}  

  

// Remote application implementation  

public class RemoteTimeServer {  

  public static void main(String args'')  {  

    try {  

      // ORB creation and initialization:  



                                                                                             668 


…………………………………………………………Page 670……………………………………………………………

      ORB orb = ORB。init(args; null);  

      // Create the server object and register it:  

      ExactTimeServer timeServerObjRef =   

        new ExactTimeServer();  

      orb。connect(timeServerObjRef);  

      // Get the root naming context:  

      org。omg。CORBA。Object objRef =   

        orb。resolve_initial_references(  

          〃NameService〃);  

      NamingContext ncRef =   

        NamingContextHelper。narrow(objRef);  

      // Assign a string name to the   

      // object reference (binding):  

      Nameponent nc =   

        new Nameponent(〃ExactTime〃; 〃〃);  

      Nameponent path'' = {nc};  

      ncRef。rebind(path; timeServerObjRef);  

      // Wait for client requests:  

      java。lang。Object sync =  

        new java。lang。Object();  

      synchronized(sync){  

        sync。wait();  

      }  

    }  

    catch (Exception e)  {  

      System。out。println(  

         〃Remote Time server error: 〃 + e);  

      e。printStackTrace(System。out);  

    }  

  }  

}  

  

正如大家看到的那样,服务器对象的实现是非常简单的;它是一个普通的 Java 类,从 IDL 编译器生成的 

返回目录 上一页 下一页 回到顶部 0 1

你可能喜欢的