服务描述符包括:
类名:包含服务实现的全限定类名的元素。
名称:包含服务名的元素。
版本:包含服务版本名的元素。
创建者:包含服务创建者名称的元素。
AssertURI:包含指向一个 XML 文件的统一资源标识符(URI)的元素。其中,XML 文件包括服务声明(规范)。
描述:包含服务描述的元素。
现在,有一个关于 Axis 的耦合注意事项。使用 Axis 作为 SOAP 引擎非常有助于实现 Web 服务的松耦合,理由如下:
1. 因为 Axis 定义了消息处理节点,该节点能够被封装以供服务请求者(客户端)与服务提供者(服务器)使用,适配器能够使用部署描述符作为一个 Web 服务部署描述符(WSDD),应用一个消息处理节点来部署 SOAP 服务。
2. Axis 中的服务通常是 SOAP 服务的实例,它包含请求与响应链,但是必须包含实际服务类的提供方。结果是,通过将消息上下文传递给消息处理节点来完成 SOAP 服务的处理。
3. Axis 客户端处理能够通过使用服务描述符和 XML 声明文件创建包含服务细节的调用工厂实例,从而构建调用对象。调用对象的属性被设定为使用相关的目标服务。然后,调用对象就通过调用 Service.createCall 工厂方法来创建。一旦建立起调用,Call.SetOperation 就通过被调用的方法名称来指定。然后,Call.invoke 通过相关的请求消息而被调用,它驱动 AxisClient.invoke,处理结果消息上下文,并向客户端返回响应消息。
在适配器的设计中,应该对性能进行特殊考虑。使用动态代理类具有性能含义。访问目标的直接方法快于访问代理类的方法。然而,这不应是在稳健体系结构与性能之间进行选择。这就是为什么目前适配器实现缓存封装器的原因。通过应用缓存,使用静态存根与基于适配器的解决方案之间的差异相对较小。根据如何实现缓存,必须提到可能的解决方案之一——记忆(Memoization)。 记忆是一种广泛使用的技术,它在 Lisp、Python 与 Perl 这样的功能编程语言中使用,给功能赋予预先计算的值。记忆一个功能将为功能添加一个透明的缓存封装,因此已经得到的值将从缓存中返回而不是每次都重建。记忆可以显著提高动态代理调用的性能。
总结我们关于此处描述的适配器的讨论,允许支持本地和远程服务实现的设计是非常重要的。服务类对适配器来说将是本地的,而远程 Web 服务则可以相互替换,因为服务类和代理类使用同样的接口来访问远程 Web 服务。本地服务类将实现与 Web 服务器远程实现相类似的方法 getFunction() 来返回功能的结果。下面的 Java 代码片断进一步说明了这一点:
清单 2. 本地服务类及其接口
public class LocalServiceImpl implements IService
{
/* get the service results */
public ….. getFunction()
{
………..
return …………;
}
}
实现了 IService 的代理类采用了方法 getFunction(),但并未考虑该方法需要访问远程 Web 服务的代码。这些代码代表了需要用来访问部署在适配器内的任意 Web 服务的代理代码。
