接下来让我们讨论两个例子。
A.5.3 用Java设计COM服务器
本节将介绍ActiveX控件、Automation服务器或者其他任何符合COM规范的服务器的开发过程。下面这个例子实现了一个简单的Automation服务器,它能执行整数加法。我们用setAddend()方法设置addend的值。每次调用sum()方法的时候,addend就会添加到当前result里。我们用getResult()获得result值,并用clear()重新设置值。用于实现这一行为的Java类是非常简单的:
1023页上程序
为了将这个Java类作为一个COM对象使用,我们将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目录。考虑到安全方面的原因(特别是涉及程序片调用COM服务的问题),只有在COM服务器已安装到trustlib目录的前提下,这些服务器才会被激活。
现在,我们已在自己的系统中安装了一个新的Automation服务器。为进行测试,我们需要一个Automation控制器,而Automation控制器就是Visual Basic(VB)。在下面,大家会看到几行VB代码。按照VB的格式,我设置了一个文本框,用它从用户那里接收要相加的值。并用一个标签显示结果,用两个下推按钮分别调用sum()和clear()方法。最开始,我们声明了一个名为Adder的对象变量。在Form_Load子例程中(在窗体首次显示时载入),会调用Adder自动服务器的一个新实例,并对窗体的文本字段进行初始化。一旦用户按下“Sum”或者“Clear”按钮,就会调用服务器中对应的方法。
1024页程序
注意,这段代码根本不知道服务器是用Java实现的。
运行这个程序并调用了CreateObject()函数以后,就会在Windows注册表里搜索指定的ProgID。在与ProgID有关的信息中,最重要的是Java类文件的名字。作为一个响应,会启动Java虚拟机,而且在JVM内部调用Java对象的实例。从那个时候开始,JVM就会自动接管客户和服务器代码之间的交流。
A.5.4 用Java设计COM客户
现在,让我们转到另一侧,并用Java开发一个COM客户。这个程序会调用系统已安装的COM服务器内的服务。就目前这个例子来说,我们使用的是在前一个例子里为服务器实现的一个客户。尽管代码在Java程序员的眼中看起来比较熟悉,但在幕后发生的一切却并不寻常。本例使用了用Java写成的一个服务器,但它可应用于系统内安装的任何ActiveX控件、ActiveX Automation服务器或者ActiveX组件——只要我们有一个类型库。
首先,我们将Jactivex工具应用于服务器的类型库。Jactivex有一系列选项和开关可供选择。但它最基本的形式是读取一个类型库,并生成Java源文件。这个源文件保存于我们的windows/java/trustlib目录中。通过下面这行代码,它应用于为外部COM Automation服务器生成的类型库:
jactivex /javatlb JavaAdder.tlb
Jactivex完成以后,我们再来看看自己的windows/java/trustlib目录。此时可在其中看到一个新的子目录,名为javaadder。这个目录包含了用于新包的源文件。这是在Java里与类型库的功能差不多的一个库。这些文件需要使用Microsoft编译器的专用引导命令:@com。jactivex生成多个文件的原因是COM使用多个实体来描述一个COM服务器(另一个原因是我没有对MIDL文件和Java/COM工具的使用进行细致的调整)。
名为Adder.java的文件等价于MIDL文件中的一个coclass引导命令:它是对一个COM类的声明。其他文件则是由服务器揭示出来的COM接口的Java等价物。这些接口(比如Adder_DispatchDefault.java)都属于“遣送”(Dispatch)接口,属于Automation控制器与Automation服务器之间的沟通机制的一部分。Java/COM集成特性也支持双接口的实现与使用。但是,IDispatch和双接口的问题已超出了本附录的范围。
在下面,大家可看到对应的客户代码。第一行只是导入由jactivex生成的包。然后创建并使用COM Automation服务器的一个实例,就象它是一个原始的Java类那