前言
結(jié)構(gòu)都是它本身所能產(chǎn)生效率的結(jié)果。任何一個成功結(jié)構(gòu)都是基于它期望的需求。我們通過期望用 Axis2 做什么來開始我們的 Axis2 之旅。
用 Axis2 做什么
在
SOAP
的術(shù)語里,一個
Web Service
交互的參與者都稱作一個
SOAP
的節(jié)點。
SOAP
消息在
SOAP
發(fā)送者和接收者之間傳遞。
SOAP
消息的傳遞是基于構(gòu)建
Web Service
交互的單元之上。
???????? Web Service
封裝了
SOAP
消息處理的復(fù)雜性,允許用戶用他們所熟悉的開發(fā)語言進行開發(fā)。
Axis2
就是通過用
Java
語言開發(fā)
Web Service
的工具,在其內(nèi)部處理
SOAP
消息,這一切對于用戶都是透明的。
Axis2 封裝了 SOAP 消息的處理,同時還有做了其他的大量的工作,這些都進一步簡化了 Web Sercice 的開發(fā)者的工作,主要有以下幾點:
提供了一個處理 SOAP 消息的框架,這個框架是極易擴展的,用戶可以在每個服務(wù)或操作上擴展它。用戶也可以在這個框架的基礎(chǔ)上對不同的消息交換模型( Message Exchange Patterns ) MEPs 進行建模。
部署 Web Service (可以用 WSDL 或者不用)。
提供了客戶端 API 用來調(diào)用 Web Service ,可以用同步或者異步的編程方式。
通過部署來配置 Axis2 和它的組件。
在不同傳輸層發(fā)送和接收 SOAP 消息。
除了上述的這些功能,在內(nèi)存和速度等性能方面也是 Axis2 的重點。 Axis2 的核心框架是構(gòu)建在 WSDL , SOAP 和 WS-Addressing 上,其他的如 JAX-RP , SAAJ 和 WS-Policy 是在核心框架之上的層。
體系結(jié)構(gòu)
在說明體系結(jié)構(gòu)前,需要說明:
Axis2 的體系結(jié)構(gòu)分離了邏輯和狀態(tài),在其內(nèi)部邏輯處理都是無狀態(tài)的,這樣就允許在幾個平行的進程間處理同樣的代碼。
所有的信息都被保存在一個信息模型中,允許系統(tǒng)阻塞和重啟。
Axis2 是模塊化的結(jié)構(gòu), Axis2 框架是構(gòu)建在核心模塊上,其他的模塊則構(gòu)建在核心模塊上。核心模塊包括:
信息模型, Axis2 定義了一個處理信息的模型,所有的狀態(tài)都保存在這個層次機構(gòu)模型中。在這個層次結(jié)構(gòu)中,系統(tǒng)處理對象的生命周期。
XML 處理模型,處理 SOAP 消息是最重要和復(fù)雜的任務(wù),它的效率是影響性能的主要因素,我們通過 AXIOM 來有效的處理 SOAP 消息和 XML 文件。
SOAP 處理模型,它控制了處理過程的執(zhí)行。這個模型定義了不同的處理階段,用戶可以在不同的階段擴展這個模型。
客戶端的 API ,它為用戶提供了方便的 API 來處理 Web Service ??梢杂脕砗?/span> IN-OUT 和 IN-only 方式的消息交換模型。
傳輸器( Transports ), Axis2 定義了傳輸框架,允許用戶定義不同的傳輸器。在 SOAP 消息處理模型中可以利用傳輸器,在實現(xiàn)中定義了幾個通用的傳輸器,當然用戶也可以在需要的時候自定義傳輸器。
非核心模塊:
代碼生成, Axis2 提供了代碼生成器,可以生成服務(wù)器端和客戶端的測試代碼。生成的代碼也就簡化了服務(wù)的部署和服務(wù)的調(diào)用,
數(shù)據(jù)綁定,
Axi2
的基本的客戶
API
允許用戶在信息集合上處理
SOAP
消息,通過封裝信息層,提供編程接口,可以使用戶方便的利用數(shù)據(jù)綁定。
?? 
信息模型
信息模型有兩個主要的層次,上下文( Contexts )和描述( Descriptions ),通過 UML 描述如下:
兩個層的連接如上圖,描述層代表靜態(tài)數(shù)據(jù),這些數(shù)據(jù)可以在 Axis2 的生命周期中通過配置文件裝載,比如部署服務(wù),操作。另一方面,在上下文的層中包括了不止一個實例的動態(tài)信息。
在兩個層次上可以提供了搜索值對的能力,當在一個層上搜索值時,會在這個個層的垂直體系上進行搜索,在結(jié)果模型中,低層的值重載了高層的值。比如,當在 Message Context 上找不到一個值時,就會在 Operation Context 上進行搜索,依次向上進行。同理在 Descriptions 也是一樣的。
這樣用戶就可以聲明和重載值,是一個非常易配置的模型,這也給系統(tǒng)帶來了弱點,就是搜索的代價。特別是對于一些不存在的值,當然分析后,開發(fā)者認為它還是可以很好的工作。
Configuration Context
|
保持了運行時狀態(tài),本質(zhì)上是 Axis2 的拷貝。
|
Axis Configuration
|
保持全部的全局配置,傳輸器,全局模塊,參數(shù),服務(wù)等。 |
Service Group Context
|
保持了不同服務(wù)組的特殊用法信息,它的生命周期開始于用戶和屬于該組的服務(wù)交互時,這個可以被用來在簡單的交互中在不同的服務(wù)(屬于同一組)中共享信息。 |
Axis Service Group
|
保持特殊服務(wù)組的部署時信息。 |
Service Context
|
在不同服務(wù)的用法中都是可用的。在一個簡單的交互中,可以被用來在同一個服務(wù)中在若干個 MEPs 中共享信息。 |
AxisService
|
保持了多個操作和服務(wù)的配置信息。 |
Operation Context
|
保持了當前的 MEPs 的信息,維護當前的 MEPs 的消息。 |
AxisOperation
|
保持了操作層的配置。 |
|
保持了當前正被執(zhí)行的消息的所有信息。 |
AxisMessage
|
到目前為止,不保存任何信息,在未來可以作為一個擴展點。 |
XML 處理模型
參考 OM Tutorial
SOAP 消息處理模型
體系機構(gòu)定義了 SOAP 處理器兩個基本動作,發(fā)送和接收 SOAP 消息。提供了兩個管道( Pipes ),或者 Flows 來執(zhí)行這兩個動作。 Axis 引擎或者 Axis2 驅(qū)動定義了 send() 和 receive() 兩個方法來實現(xiàn) Pipes 。兩個管道為 In Pipe 和 Out Pipe ,通過合并這兩個 Pipes 來構(gòu)建 MEPs 。
通過處理器( handler )來實現(xiàn) SOAP 消息處理的易擴張性。當一個 SOAP 消息被處理時,被注冊的處理器就會執(zhí)行,處理器可以注冊在全局變量,服務(wù),或操作范圍內(nèi),最后處理器鏈從所有的范圍內(nèi)計算合并所有的處理器。
處理器也扮演了攔截器( Intercepter )的作用,他們處理部分 SOAP 消息,提供附加的服務(wù),通常處理器工作在 SOAP 頭上,也可以訪問和改變 SOAP 體。
當一個 SOAP 消息通過客戶端 API 發(fā)送, Out Pipe 就開始操作, Out Pipe 觸發(fā)處理器,被一個將 SOAP 消息送到端點( endpoint )的發(fā)送傳輸器結(jié)束,在目標端的接收傳輸器接收。在接收端 In Pipe 開始讀 SOAP 消息。 In Pipe 由處理器和消息接收者組成。
上述發(fā)生的消息處理過程發(fā)生在所有的消息交換中。在 Axis2 中處理一消息后就會創(chuàng)建另一消息,在新的消息中,更復(fù)雜的模型可能出現(xiàn)。
兩種類型 Pipe 和服務(wù)器 / 客戶端模型類似, SOAP 處理模型簡化了復(fù)雜性,為用戶提供了抽象的接口。 Pipe 的不同階段 phases 都已命名。處理器通常運行在一個階段中,階段提供了一種預(yù)定處理器的機制。兩種 Pipe 都內(nèi)建了 phases ,也都為用戶提供了 User Phases ,可以由用戶自定義。
下圖中可以看到 User Phases
Axis2 默認處理模型
Axis2 有很多內(nèi)建在 Phases 中的處理器,它們可以為 Axis2 創(chuàng)建默認配置。在下節(jié)中,我們會仔細研究如何擴展 Axis2 的默認處理模型。
Axis2 中有四種特殊的處理器:
分發(fā)器( Dispatchers )查找服務(wù)和 SOAP 消息的操作。通常運行在 In-Pipe 的 dispatch 階段。根據(jù)不同的條件,如 WS-Addressing , URI 信息, SOAP Action 信息來分配特殊的操作。
消息接收器( Message Receiver ) 讀 SOAP 消息,運行在 In-Pipe 的 Message Processing 階段。
發(fā)送傳輸器( ???? Transport Sender )發(fā)送 SOAP 消息,永遠運行在 Out-Pipe 中。
處理收到的 SOAP 消息
由接收傳輸器收到消息,一旦消息到達,傳輸頭就會被解析,消息上下文( Message Context )就會創(chuàng)建,然后通過消息上下文 In-Pipe 就會被執(zhí)行。
讓我們看下在執(zhí)行過程中每個階段都發(fā)生了什么,處理過程在服務(wù)端和客戶端都會發(fā)生,這里說明一個特殊的雙向傳輸,在 In-Pipe 開始的四個階段可能不會發(fā)生。
傳輸階段,在這個階段處理器從傳輸配置中抽出,根據(jù)規(guī)則執(zhí)行。
預(yù)分發(fā)階段,由于服務(wù)還未存在,處理器會在全局使用。
分發(fā)階段,如果服務(wù)還為發(fā)行,分發(fā)器就會在此階段查找服務(wù)。
用戶階段,運行用戶自定義處理器。
消息驗證階段,在這個階段驗證 SOAP 消息處理是否正常執(zhí)行。
消息處理階段,在這里執(zhí)行 SOAP 消息的商業(yè)邏輯,每個操作都注冊了一個消息接收器,消息接收器(關(guān)聯(lián)到特定操作)就會作為這個階段的最后一個處理器執(zhí)行。
可能還有其他的處理器,用戶也可以自定義處理器來重載每個階段的處理機制。
發(fā)送消息的處理過程
Out-Pipe 是相對簡單,因為此時服務(wù)都已被所知, Out-Pipe 由消息接收器或客戶 API 實現(xiàn)。
消息初始化階段, Out-Pipe 的第一個階段,作為自定義處理器的存放文件夾。
用戶階段,執(zhí)行用戶階段的處理器
傳輸階段,執(zhí)行從傳輸配置層的傳輸處理器,作為傳輸處理器的最后處理器發(fā)送 SOAP 消息到目的端。
擴展消息處理模型
以上我們討論了 Axis2 默認處理模型,現(xiàn)在我們討論下 SOAP 消息處理的擴展機制,很多 SOAP 引擎研究也集中在其擴展性。
根據(jù)處理器和階段使在 SOAP 處理中更容易的修改處理過程,階段概念使在處理器之間加入新的處理器,也就更容易擴展默認的處理過程。
用處理器擴展 SOAP 處理模型
通過階段規(guī)則( Phase rule )將處理器放在不同位置定制階段來擴展 SOAP 處理模型。
作為一個階段的第一個處理器
作為一個階段最后一個處理器
在一個給定處理器之前
在一個給定處理器之后
通過模塊擴展 SOAP 處理模型
Axis2 定義了一個叫模塊( Module )的實體,由模塊來引入處理器和 Web Service 操作,在 Axis2 中的模塊作為一個包,包中包括了一些處理器和相關(guān)的關(guān)于規(guī)則的描述,模塊是有可用性和被用時,可用性表示模塊存在于系統(tǒng)中,但仍沒被激活,就是被包括在模塊中的處理器沒有在處理機制中,當一個模塊被用時,它就會被激活,然后在階段中找到合適的位置,這些處理器就會按照上面的方法執(zhí)行。通常模塊被用來實現(xiàn)在 WS-Addressing 時的 WS-* 功能。
除了上面基于 handlers 實現(xiàn)擴展外, WS-* 參考建議另一種增加操作( Operations )的方法,比如,用戶在服務(wù)中增加創(chuàng)建序列( Create Sequence )的操作,需要在服務(wù)端可以用,就可以通過在模塊中定義操作來實現(xiàn),一旦模塊被服務(wù)所用,需要的操作就會被增加到服務(wù)中。
服務(wù),操作或系統(tǒng)都可以利用模塊,一旦模塊被用到,在其中定義的處理器,操作就會添加到這個實體中。
當 Axis2 正在運行時,模塊就不能被添加,除非系統(tǒng)重啟。
部署
部署模型提供了詳細配置 Axis2 的機制,主要有三個部分來配置 Axis2
Axis2.xml 文件
這個文件為客戶端和服務(wù)器端提供了全局的配置,主要包括下面的信息。
全局參數(shù)
注冊的發(fā)送傳輸器( Transport In )和接收傳輸器( Transport Out )
用戶定義的階段名
全局被用到的模塊
全局的消息接收器
服務(wù)包( Service Archive )
服務(wù)包必須包含 META-INF/services.xml 文件和一些相關(guān)的類, services.xml 包含以下信息
服務(wù)級的參數(shù)
服務(wù)級的模塊
服務(wù)中特定消息接收器
服務(wù)內(nèi)部的操作
模塊包( Module Archive )
模塊包必須包含 META-INF/module.xml 文件和一些相關(guān)的類, module.xml 包含了模塊參數(shù)和在其中定義的操作。
當系統(tǒng)啟動時, Axis2 就會創(chuàng)建 Axis 的配置,首先會找 axis2.xml ,構(gòu)建全局配置,接下來就會檢查模塊包和服務(wù)包,這樣相關(guān)的服務(wù)和模塊就會被添加到配置中,然后在配置基礎(chǔ)上,構(gòu)建上下文, Axis2 就準備接收和發(fā)送 SOAP 消息,服務(wù)也可以熱部署,有一個線程循環(huán)的檢測容器,看是否有新的服務(wù)被部署。
客戶端 API ( Client API )
有三個參數(shù)決定了 Web Service 的交互
消息交換模型( MEP )
傳輸器的行為,是 One-way 或者 Two-way
客戶端 API 是同步或者異步
由于這三個參數(shù)的變化導(dǎo)致了很多語義的不確定性,盡管 Axis2 是構(gòu)建在運行多種消息交互的核心上,但開發(fā)者一般都用兩種主要的 MEP 。
在 Client API 中,兩種支持的傳輸器是單向( One-Way )和雙向( Request-Response )。是基于 ServiceClient 類來實現(xiàn)的, Axis2 中有每種 MEP 的擴展支持。
單向消息傳輸
ServiceClient 為用戶提供了簡單的接口,由 ServiceClient 提供的 fireAndForge 支持 One-Way 方式, Axis2 支持 HTTP/SMTP 和 TCP 傳輸, HTTP 的情況,如果返回通道( Channel )不可用,就會返回 HTTP 202 OK 。
雙向( Request Response )消息傳輸
由在 ServiceClient 中的 sendReceive() 提供,為用戶提供了簡單的接口,在客戶 API 中有四種方法配置消息交換。
阻塞或非阻塞方式,由 sendReceive() 和 sendReceiveNonBlocking() 來決定。
發(fā)送傳輸器,傳輸器被用來發(fā)送 SOAP 消息
監(jiān)聽傳輸器,傳輸響應(yīng)收到信息。
利用分離通道,決定是否響應(yīng)是通過分離的傳輸連接或者非分離的來發(fā)送。如果發(fā)送和監(jiān)聽器是相同的機會失敗,這樣就是雙向傳輸。
上面四個參數(shù)的不同就會使 Axis2 進行不同的操作。
傳輸器
Axis2 有兩種不同傳輸結(jié)構(gòu), transport in 配置和 transport out 配置,通過消息上下文來訪問他們。
服務(wù)器利用 transport in 來收到消息, outgoing transport 是由尋址信息( Addressing Information ) (ReplyTo 或 FaultTo) 決定的,如果尋址信息不可用,則 outgoing transport 和 incoming transport 相同。
在客戶端,用戶可以自由使用 transport 。
transport in 配置和 transport out 配置包含以下信息
對外的傳輸發(fā)送器
對內(nèi)的傳輸監(jiān)聽器
傳輸?shù)膮?shù)
傳輸?shù)奶幚砥?/span>
每個對外的傳輸配置都定義了一個傳輸代理,傳輸發(fā)送器通過自己的傳輸發(fā)送消息。
傳輸接收器等待 SOAP 消息,一旦 SOAP 消息到,就會用 In Pipe 來處理消息。
Axis2 目前支持以下的傳輸
HTTP ,在 HTTP 的傳輸中,傳輸監(jiān)聽器是一個 Servlet 或者是由 Axis2 提供的 org.apache.axis2.transport.http.SimpleHTTPServer ,傳輸發(fā)送器用 commons-httpclient 來連接和發(fā)送 SOAP 消息。
TCP ,這是最簡單的傳輸,但需要 WS-Adressing 支持
SMTP ,需要 Email 帳號,傳輸接收者在確定的時間間隔內(nèi)檢測郵件的到來。
代碼生成
盡管代碼生成的目標沒有改變,但在 Axis2 中采用了一種不同的代碼生成方法,主要變化是采用了模版,命名為 XSL 來以各種語言生產(chǎn)代碼,提供了很好的靈活性。
主要思想,設(shè)置生成器來生成 XML ,利用模版解析 XML 來生成代碼文件,下圖描述了生成工具的結(jié)構(gòu)
不管代碼是如何生成的,關(guān)鍵是和從 WSDL 生成信息相同,代碼生成器利用 WOM ( WSDL Object Model )操作 WSDL 文件,傳輸信息到 Emitter , Emitter 生成 XML ,然后 XML 由相應(yīng)的 XSL 解析生成代碼。除非用到的模版不同,不管編程如何,處理過程都是相同的。
數(shù)據(jù)綁定
集成代碼生成引擎
Axis
序列化和發(fā)序列化
AXIOM 是基于 StAX ( Streaming API for XML ) API , Xml-beans 支持 StAX 的數(shù)據(jù)綁定,通過 AXIOM 用 Xml-bean 來實現(xiàn),在代碼生成階段,對于每個 WSDL 的操作都有些支持的類, WSDL 的操作中有很多有用的方法,可以從 AXIOM 反序列化到數(shù)據(jù)綁定對象,也可以從數(shù)據(jù)綁定對象序列化到 AXIOM 。比如在 WSDL 文件中有一個叫 echoString 的方法,一旦代碼生成, echoStringDatabindingSupporter.java 類就會生成,其中包括類似于以下的代碼,
public static org.apache.axis2.om.OMElementtoOM(org.soapinterop.xsd.EchoStringParamDocument param) // 這個方法處理序列化 public static org.apache.xmlbeans.XmlObject fromOM(org.apache.axis2.om.OMElement param, java.lang.Class type) // 這個方法處理反序列化 public static org.apache.xmlbeans.XmlObject getTestObject(java.lang.Class type) // 由給定的數(shù)據(jù)綁定類型創(chuàng)建樣本對象 |