友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!
第三电子书 返回本书目录 加入书签 我的书架 我的书签 TXT全本下载 『收藏到我的浏览器』

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

快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部! 如果本书没有阅读完,想下次继续接着阅读,可使用上方 "收藏到我的浏览器" 功能 和 "加入书签" 功能!


    result = 0;  

    addend = 0;  

  }  

}  

  

为了将这个 Java 类作为一个  对象使用,我们将 Javareg 工具应用于编译好的Adder。class 文件。这个工 

具提供了一系列选项;在这种情况下,我们指定Java 类文件名(〃Adder〃),想为这个服务器在注册表里置 

入的ProgID (〃JavaAdder。Adder。1〃 ),以及想为即将生成的类型库指定的名字(〃JavaAdder。tlb〃)。由于 

尚未给出CLSID,所以 Javareg 会自动生成一个。若我们再次对同样的服务器调用 Javareg,就会直接使用现 

成的CLSID。  

  

javareg /register  

/class:Adder /progid:JavaAdder。Adder。1  

/typelib:JavaAdder。tlb  

  

Javareg 也会将新服务器注册到 Windows 注册表。此时,我们必须记住将 Adder。class 复制到 

WindowsJavatrustlib 目录。考虑到安全方面的原因(特别是涉及程序片调用 服务的问题),只有在 

 服务器已安装到trustlib 目录的前提下,这些服务器才会被激活。  

现在,我们已在自己的系统中安装了一个新的 Automation 服务器。为进行测试,我们需要一个 Automation 

控制器,而 Automation 控制器就是 Visual Basic (VB )。在下面,大家会看到几行VB 代码。按照 VB 的格 

式,我设置了一个文本框,用它从用户那里接收要相加的值。并用一个标签显示结果,用两个下推按钮分别 

调用 sum()和 clear()方法。最开始,我们声明了一个名为Adder 的对象变量。在Form_Load 子例程中(在窗 

体首次显示时载入),会调用Adder 自动服务器的一个新实例,并对窗体的文本字段进行初始化。一旦用户 

按下“Sum”或者“Clear”按钮,就会调用服务器中对应的方法。  

  

Dim Adder As Object  

  

Private Sub Form_Load()  

    Set Adder = CreateObject(〃JavaAdder。Adder。1〃)  

    Addend。Text = Adder。getAddend  

    Result。Caption = Adder。getResult  

End Sub  

  

Private Sub SumBtn_Click()  

    Adder。setAddend (Addend。Text)  

    Adder。Sum  

    Result。Caption = Adder。getResult  

End Sub  

  

Private Sub ClearBtn_Click()  

    Adder。Clear  

    Addend。Text = Adder。getAddend  

    Result。Caption = Adder。getResult  

End Sub  

  

注意,这段代码根本不知道服务器是用Java 实现的。  



                                                                                             664 


…………………………………………………………Page 666……………………………………………………………

运行这个程序并调用了 CreateObject()函数以后,就会在Windows 注册表里搜索指定的ProgID。在与 

ProgID 有关的信息中,最重要的是Java 类文件的名字。作为一个响应,会启动Java 虚拟机,而且在 JVM 内 

部调用Java 对象的实例。从那个时候开始,JVM 就会自动接管客户和服务器代码之间的交流。  



A。5。4  用 Java 设计  客户  



现在,让我们转到另一侧,并用Java 开发一个 客户。这个程序会调用系统已安装的 服务器内的服 

务。就 目前这个例子来说,我们使用的是在前一个例子里为服务器实现的一个客户。尽管代码在Java 程序员 

的眼中看起来比较熟悉,但在幕后发生的一切却并不寻常。本例使用了用 Java 写成的一个服务器,但它可应 

用于系统内安装的任何 ActiveX 控件、ActiveX Automation 服务器或者 ActiveX 组件——只要我们有一个类 

型库。  

首先,我们将Jactivex 工具应用于服务器的类型库。Jactivex 有一系列选项和开关可供选择。但它最基本 

的形式是读取一个类型库,并生成 Java 源文件。这个源文件保存于我们的windows/java/trustlib 目录中。 

通过下面这行代码,它应用于为外部 Automation 服务器生成的类型库:  

  

jactivex /javatlb JavaAdder。tlb  

  

Jactivex 完成以后,我们再来看看自己的windows/java/trustlib 目录。此时可在其中看到一个新的子目 

录,名为 javaadder。这个目录包含了用于新包的源文件。这是在 Java 里与类型库的功能差不多的一个库。 

这些文件需要使用Microsoft 编译器的专用引导命令:@ 。jactivex 生成多个文件的原因是  使用多个 

实体来描述一个 服务器(另一个原因是我没有对MIDL 文件和 Java/ 工具的使用进行细致的调整)。  

名为Adder。java 的文件等价于MIDL 文件中的一个 coclass 引导命令:它是对一个  类的声明。其他文件 

则是由服务器揭示出来的 接口的 Java 等价物。这些接口(比如Adder_DispatchDefault。java)都属于 

 “遣送”(Dispatch )接口,属于Automation 控制器与Automation 服务器之间的沟通机制的一部分。 

Java/ 集成特性也支持双接口的实现与使用。但是,IDispatch 和双接口的问题已超出了本附录的范围。  

在下面,大家可看到对应的客户代码。第一行只是导入由 jactivex 生成的包。然后创建并使用  

Automation 服务器的一个实例,就象它是一个原始的 Java 类那样。请注意行内的类型模型,其中“例示” 

了 对象(即生成并调用它的一个实例)。这与 对象模型是一致的。在  中,程序员永远不会得到 

对整个对象的一个引用。相反,他们只能拥有对类内实现的一个或多个接口的引用。  

 “例示”Adder 类的一个Java 对象以后,就相当于指示  激活服务器,并创建这个 对象的一个实例。 

但我们随后必须指定自己想使用哪个接口,在由服务器实现的接口中挑选一个。这正是类型模型完成的工 

作。这儿使用的是“默认遣送”接口,它是Automation 控制器用于同一个Automation 服务器通信的标准接 

口。欲了解这方面的细节,请参考由Ibid 编著的《Inside 》。请注意激活服务器并选择一个  接口是 

多么容易!  

  

import javaadder。*;  

  

public class JavaClient {  

  public static void main(String '' args) {  

    Adder_DispatchDefault iAdder =  

         (Adder_DispatchDefault) new Adder();  

    iAdder。setAddend(3);  

    iAdder。sum();  

    iAdder。sum();  

    iAdder。sum();  

    System。out。println(iAdder。getResult());  

  }  

}  

  

现在,我们可以编译它,并开始运行程序。  

  

1。 。ms。 包  

。ms。包为  的开发定义了数量众多的类。它支持GUID 的使用——Variant (变体)和SafeArray  



                                                                                   665 


…………………………………………………………Page 667……………………………………………………………

Automation (安全数组自动)类型——能与ActiveX 控件在一个较深的层次打交道,并可控制  异常。  

由于篇幅有限,这里不可能涉及所有这些主题。但我想着重强调一下 异常的问题。根据规范,几乎所有 

 函数都会返回一个 HRESULT 值,它告诉我们函数调用是否成功,以及失败的原因。但若观察服务器和客 

户代码中的 Java 方法签名,就会发现没有HRESULT 。相反,我们用函数返回值从一些函数那里取回数据。 

 “虚拟机”(VM )会将Java 风格的函数调用转换成  风格的函数调用,甚至包括返回参数。但假若我们在 

服务器里调用的一个函数在 这一级失败,又会在虚拟机里出现什么事情呢?在这种情况下,JVM 会认为 

HRESULT 值标志着一次失败,并会产生类。ms。。FailException 的一个固有 Java 异常。这样一来, 

我们就可用 Java 异常控制机制来管理 错误,而不是检查函数的返回值。  

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



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 源码,也会生成用于汇集方法自变量的代 

码,并可发出远程调用。我们将这种代码称为“根干”(St
返回目录 上一页 下一页 回到顶部 1 1
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!