原文地址 http://www.devx.com/enterprise/Article/43086/0/page/1
利用Web Services 将 .NET 和 Java 技术融合很容易,但对于许多任务来说,Web Services 并不是Java / .NET互操作性的解决方案。
Web services 对于集成网络通信的独立组件很有用。当使用直接的调用/返回方式时,涉及的数据类型的数量非常有限,建立并让它们工作很简单。因为,web services 是标准的,所以,用它将 .NET 和 Java 融合也很容易,这让一些人相信,web services 是 Java/.NET 互操作性的灵丹妙药,但通常不是。
简单在搜索引擎搜索一下“Java/.NET互操作性”,会得到很多检索结果,参加2009年6月 “Microsoft keynote at JavaOne 2009”会议的人都相信 Web services 是最好的方式。很不幸,对于很多任务来说,Web services 并不是Java/.NET互操作性的理想解决方案。很多任务使用 Web services 几乎是不可能的。下面,我会列举三个用 Web services 实现 Java/.NET 互操作的情景,从中可以看出,用Web services并不是一个明智的选择,甚至愚蠢。
首先,先准确定义一下,什么是 Java和.NET互操作性。诚然,这不太容易,但一个真正的 Java/.NET 互操作机制应该允许你在任何地方替换用 Java 编写的代码,你一般会用 .NET 语言编写的代码来替换。换句话说,允许你从 .NET 代码中访问任何基于Java的实体(如对象,类或是方法),反之亦如此。对于很多开发者和架构师不会使用 web services 的情景来说,定义Java/.NET互操作性是很有益的。
情景1. 将 .NET UI 控件嵌入到 Java 应用程序
考虑一个情况:你想要在基于AWT的Java应用程序中使用一个Windows窗体控件。
标准的做法是获得与AWT容器对等的句柄(底层 Windows 对象,the underlying Windows object),然后使用该句柄设置Windows窗体控件的父对象为AWT容器(也就这些,这就是嵌入工作的主要要求)。你不能使用 Web Service 实现这类互操作性。
Web Service是松散耦合(loosely coupled)。服务和客户端运行在独立的进程中。在独立的进程中,你不能交换窗口句柄。而句柄只有在同一个进程中才是有效的、有意义的。换句话说,这是一个必须紧密耦合(tightly coupled)的互操作性情景。Web Service 就不能适应这种情况。想在基于Java的GUI应用程序中嵌入基于.NET的控件,开发人员必须想另外的办法,反之亦如此。若想将基于 .NET 的控件嵌入到基于 Java GUI的应用程序(或反之亦然),开发人员就不得不使用其他方法。
情景2. 从 Java 应用程序调用 .NET 程序集
假设你有一个基于 .NET 程序集,想在其他基于 Java 的应用程序中使用。很多因素能导致这种情况,例如:
1) 已在 .NET 开发中使用了这个库,你想继续使用这个库(库都是有特殊、专门的用途的);
2) 已购买 .NET 库,不想再购买Java库;
3) 不考虑平台的话,这个库可能是最好使用的。
在某些情况下,你可以使用 Web Service 在 Java 中访问 .NET 代码,但是,这种似乎有点小题大做。通过简单访问一个库,建立一个服务,显然没意义。Web Service更适合两个大的独立组件之间的通信,而不是将一个库集成到一个大的系统中。如果库都在同一个机器上,那么创建一个Web service,让一个应用程序访问一个库,显然有点过了。在这种情况下,在Java 应用程序进程内运行基于 .NET 库,更有意义。但是用 Web Service 不能做到这点。
情景3. 用一个 Java API 注册一个 .NET 监听(.NET Listener)
假设你有一个 JMS 消息服务(Java Message Service)架构(JMS infrastructure),你想创建一个 .NET 组件,向它发送消息,并从它那里接收消息。
一般地,你通过调用 JMS API 中的发送方法,向 JMS 发送消息,用 JMS 设施注册监听来接受消息。当消息到达时,监听就会执行。
你也可以使用 Web Service来完成,但它并不适于处理异步通信。如果你真要使用 Web Service 实现异步通信,你有两个选择:
1) 实现一个轮询机制,客户端反复轮询服务以便获得结果。当得到结果后,服务将其放在一个预定的位置,轮询操作就会发现它。
2) 实现一个回调机制,客户端留下一个回复地址(return address)。当获得结果后,服务调用这个回复地址。不幸的是,这两个机制都需要实现一个很大的基础架构。
在轮询机制情况下,你需要实现轮询机制,以及为服务放置结果的机制,以便轮询机制能看到它。
在回调机制情况下,你必须在客户端嵌入一个全新的“反向”Web Service,以便原始服务可以与它通信,并返回异步结果。这两个方法都缺少相称性。如果你只是想简单地让一个应用程序调用一个库,Web Service 需要实现与目前任务完全不相称的机制。当某一个动作发生时,注册一个监听器,是最好的例子。必须要有更好的方式来完成。
需要额外的工具为 Java /.NET 互操作性
对于复杂的、但仍然比较简单的 Java/.NET 互操作需求(如在 Java 应用程序中调用 .NET 库,或使用Java API注册一个 .NET 监听器),Web Service使你浪费时间,去做别人已做好的事(reinvent the wheel)。你必须建立复杂的基础架构——通过 sock 交换 XML——来完成本应该很简单的任务。这是愚蠢的。而且对于其它任务,如在 Java 应用程序中嵌入 .NET UI 控件,Web Service根本是不可能的。
开发人员和架构师工具箱有很多 Java/.NET 互操作性的解决方案,除了 web services 外。对某些情况,它们很有用。但是对于许多互操作任务,你需要不同的工具。当 Web Service 不合适或是无法工作时,Java/.NET 桥接器(bridge)会很好地工作,甚至在那些可以用 Web Service 的情况中,效率更高、更容易使用。
如果你理解了 Web Service 在互操作性方面的局限性,并熟悉其它解决方案,你就可以在你的应用程序中充分利用Java和.NET技术。