结构概览
Axis
包含多个协同工作的子系统,我们在之后会一一介绍。首先介绍一下
Axis
的核心是如何工作的。
Axis
的
Handlers
和
Message Path
简而言之,整个
Axis
就是关于处理
Message
的。当核心
Axis
处理逻辑在运行的时候,按顺序激活一系列的
Handlers
。它们的顺序由两个因素来决定
-----
部署配置以及
engine
的类型
(
客户端
/
服务器端
)
。传递到每个
Handler
调用的对象叫做
MessageContext
。
MessageContext
是一个结构体,包含很多重要的部分:请求消息、响应消息和很多属性。事实上远远不止这些。
有两种基本的方式来调用
Axis
:
作为一个服务器,传输监听器
(Transport Listener)
会创建
MessageContext
并调用
Axis
处理框架
作为一个客户端,应用程序代码
(
使用
Axis
的客户端编程模型来编写的
)
创建一个
MessageContext
并调用
Axis
处理框架
在每一种情况中,
Axis
框架的工作就是简单的将每个
MessageContext
结果传送到配置好的
Handlers
集合,每个
Handler
都有机会来对
MessageContext
进行操作。
服务器
Message Path
服务器端
message path
通过下图表示。小圆柱体代表
Handlers
,大一些的,包含圆柱体的圆柱体表示
Chains(
有顺序的
Handlers
集合
)
。

当消息以特定的传出协议到达传输监听器时,本例中,我们假设是
Http servlet
。
Listener
将特定协议的数据设置到
Message
对象中,然后将
Message
设置到
MessageContext
中。
MessageContext
同时通过
Listener
加载各种属性
---
在本例中,
"http.SOAPAction"
属性会被设置成
SOAPAction HTTP
和
header
。传输监听器同时还将
transportName
属性设置到
MessageContext
中,在本例中为
”http”
。一旦将
MessageContext
准备好后,
Listener
将其转交给
AxisEngine
。
AxisEngine
的要做的第一件事就是根据名字查找
transport
。
transport
是包含一个请求链,一个响应链或者两者都有的对象。链
(Chain)
就是一个
Handler
,但是它还包含一个
Handler
序列,按顺序被调用。如果
transport
请求链存在,将被调用,将
MessageContext
传送到它
(transport
请求链
)
的
invoke()
方法。这将导致调用请求链中的所有
Handlers
。
transport
请求
Handler
结束后,
Axis Engine
查找
global
请求链
,如果配置了
global
请求链的话,那么调用指定的
Handlers
。
上述过程中的一些地方,一些
Handler
已经设置了
MessageContext
的
serviceHandler
属性
(
在
HTTP
传输中,这通常由
URLMapper Handler
来完成,
URLMapper Handler
将一个
URL
,例如
http://localhost/axis/services/AdminService
,映射到
AdminService
服务
)
。
这个属性决定了
Handler
,这个
Handler
用来执行特定服务的功能,例如对后台对象执行
RPC
调用。
Axis
中的服务是
SOAPService
类
(org.apache.axis.handler.soap.SOAPService)
的实例
,
它可能包含请求链和响应链
(
和前面介绍的
transport/global
相似
)
,并且必须包含一个
provider
,也是一个
Handler
,负责实现服务的实际后台逻辑。
对于
RPC-style
的请求,
provider
是
org.apache.axis.providers.java.RPCProvider
类。这也是一个
Handler
,当被调用时,它调用一个后台的
Java
对象,
Java
对象的类由
className
参数在部署时设置。它使用
SOAP RPC
方式来决定调用哪个方法,并确保输入的
XML-encoded
参数的类型与被调用方法要求的参数的类型一致。
客户端的
Message Path
除了范围的顺序相反之外,客户端的
Message Path
和服务器端的相似。如下图所示:

如果存在服务
Handler
的话,首先在客户端调用它,不存在
provider
,因为服务是由远程节点提供的,但是仍然有可能存在请求链
/
响应链。请求链和响应链在系统外对请求消息执行任意的特定服务的处理,同样在响应返回到调用者时,也对响应执行相同的处理。
如果存在
global
请求链,那么在执行完服务请求链后,它将被调用,然后是传输请求链。然后调用
Transport Sender
来发送消息。
Transport Sender
是一个特殊的
Handler
,用于执行实际的特定协议的操作,操作包括从目标
SOAP
服务器获取消息和向目标服务器发送消息。响应被添加到
MessageContext
的
responseMessage
属性中,然后
MessageContext
被传送回来,依次经过
transport
、
global
,最后是
service
。
子系统
为了明确的分工与划分
Axis
标准组件,
Axis
由一些子系统共同工作。子系统可以在整个系统不使用的情况下独立使用。
下面的示意图展示了子系统的层次部署。底层独立于上层。层叠的方框表示互相独立,虽然不一定必须彼此排斥。例如,
HTTP
,
SMTP
和
JMS
传输彼此独立,但是也可以共同使用。

事实上,
Axis
的源代码并没有像上面的图一样区分的如此明显。一些子系统散布在多个
packages
并且一些
packages
包含了多个子系统。以后会对这个结构进行修改。
1.
消息流子系统
Handlers
和
Chains---
处理器和链
Handlers
被序列调用来处理消息。在序列中的某些点,一个
Handler
可能发送请求并接收响应,或者处理请求和产生响应。这样的
Handler
叫做
pivot point(
枢纽点、中心点
)
。如上所述,
Handlers
是特定协议的、特定服务的或者是全局的。
这三种不同的
Handlers
被组合到
Chains
中。所以
Handlers
的整个序列包含了三个
Chains
,
transport
、
global
和
service
。下图显示了两个
handlers
序列:客户端序列
(
左侧
)
和服务器端序列:

一个
Web Service
不一定非要针对每个请求都发送响应,虽然大多数是发送的。但是,响应
Handlers
在
message path
中同样很有用,即便没有响应消息,例如停止计时器、清理资源等等。
Chain
是合成的
Handler
。也就是说,它聚集了一个
Handlers
的集合,它本身也实现了
Handler
接口,如下面的
UML
图所示:

public interface Chain extends Handler {
public void addHandler(Handler handler);
public void addHandler(Handler handler);
public boolean contains(Handler handler);
public Handler[] getHandlers();
};
Chain
和设计模式的责任者模式也有相似之处,也就是说,一个
Chain
中的请求通过序列中的每一个
Handler
,直到它被处理为止。虽然一个
Axis Chain
可能在很多
Handlers
中都对请求进行处理,但是它和责任者模式有同样的优点:灵活性和追加新功能的方便性
(
易扩展性
)
。
回到消息处理
-----
一个消息通过传递到合适的
Chains
来进行处理。一个消息上下文用来将
Message
和关联的环境属性传递到
Handlers
序列。
Axis Chains
是通过每次增加一个
Handler
脱机构造的,然后它们变为在线的,消息上下文开始被传递到
Chains
。可能多个消息上下文并发通过同一个
Chain
。一旦
Chain
是在线的状态时,就不再添加
Handlers
。如果需要增加或者删除一个
Handler
,必须对
Chain
进行
”cloned”
操作,对
clone
进行操作,然后将
clone
变为在线,当旧的
Chain
不再被使用时,就销毁旧的
Chain
。消息上下文在完成之前仍然使用旧的
Chain
。这意味着正在处理消息上下文的
Chain
不需要理会
Handler
的追加与移除
-------
非常重要的一个简化。
部署注册器具有
Handlers
和
Chains
的工厂。
Handlers
和
Chains
可以被定义成具有
’per-access’
、
’per-request’
或者
’singleton’
范围。虽然注册器只能通过以下的办法来进行区别:
对于每个请求,创建
Non-singleton
范围的对象。
仅创建
singleton
范围的对象一次,然后持有这个对象,在之后创建的请求都使用这个对象。
Targeted Chains
目标链
Targeted Chain
是一种特速类型的
chain
,可能包含下面的一些或者全部:
请求
Handler
pivot Handler
支点
Handler
响应
Handler
下面的类图表示了
Targeted Chain
和
Chains
的关系。注意由于
Targeted Chain
实现了
Chain
接口,所以
Targeted Chain
是
Handlers
的聚集。
(Chain
是
Handlers
的聚集
)

服务是一种特殊的
Targeted Chain
,它的
pivot Handler
就是
provider
。
A service is a special kind of Targeted Chain in which the pivot Handler is known as a provider.
Fault Process
错误处理
现在考虑一下发生了错误的时候怎么处理。抛出异常的
Handler
的外层的
Handler
被驱动
onFault
方法,按照相反的顺序。这个向后扫描的范围很有意思:所有当前
Message Context
之前被调用的
Handlers
被驱动。
Message Context
消息上下文
现在的
Message Context
的结构如下图所示,每个消息上下文都和一个请求消息
and/or
响应消息相关联。每个
Message
都有一个
SOAPPart
和
Attachments
对象,
SOAPPart
和
Attachments
都实现了
Part
接口。

消息上下文要结合
Axis
框架仔细考虑。既然消息上下文是在
Handler
接口上出现的,它就不应该绑定到或者偏重于
SOAP
。现在的实现是偏重于
SOAP
,因为
setServiceHandler
方法将指定的
Handler
局限于
SOAPService
。
Engine
引擎
Axis
有一个
AxisEngine
抽象类,并且有两个具体的子类:
Axis
驱动客户端
handler chains
,
AxisServer
驱动服务器端
handler chains
。这几个类之间的关系如下:

Engine Configuration
引擎配置
EngineConfiguration
接口是
engine
接口配置
Handler
工厂和全局属性的途径。
EngineConfiguration
的实现类的一个实例被创建后,必须传送给
engine
,并且一旦
EngineConfiguration
的内容被修改了,必须要通知
engine
。
engine
持有
EngineConfiguration
的一个引用,并使用它来获取
Handler
工厂和全局属性。
EngineConfiguration
接口属于消息流子系统,也就是说,消息流子系统不依赖于管理子系统。
2.
管理子系统
管理子系统提供了配置
Axis
引擎的方法。引擎需要的配置信息是运行时实例的集合
(eg.Chains
和
SOAPServices)
和引擎的全局配置选项。
消息流子系统的
EngineConfiguration
接口由
Administration
子系统实现。
FileProvider
可以使
engine
通过一个包含部署描述符的本地文件被静态的配置。部署描述符可以被
WSDDDeployment
类来使用。
SimpleProvider
可以使
engine
被动态的配置。

WSDD-Based Administration
基于
WSDD
的管理
WSDD
是一个基于
XML
语法的部署描述符,部署描述符用于静态配置
Axis
引擎。每个
Handler
需要根据
Handler
工厂的具体类的名字、
handler
的一系列选项以及一个生命周期范围来进行配置。
WSDD
语法的结构映像到一个工厂类层次。下面的图显示了运行时它们
(
工厂类
)
生成的的类和类型。
