SCA 是由幾家國內(nèi)外知名企業(yè)聯(lián)合制定的,他們成立了一個名為OSOA的組織,SCA
標(biāo)準(zhǔn)目前還在完善階段,它于
2005
年
11
月發(fā)布了
0.9
版本,目前版本已經(jīng)到了
0.96
。在
0.9
版本中,
SCA
標(biāo)準(zhǔn)就提出了
Java
實(shí)現(xiàn)以及
C++
實(shí)現(xiàn)標(biāo)準(zhǔn),而且在以后的版本中,會陸續(xù)加入其他的實(shí)現(xiàn)標(biāo)準(zhǔn),也就是說
SCA
并不是只針對某一種語言的,不同語言或者環(huán)境之間通過開放的,標(biāo)準(zhǔn)的技術(shù)來實(shí)現(xiàn)互操作,比如我們常見的WebService等
。
SCA
提出的這套基于
SOA
去構(gòu)建企業(yè)應(yīng)用的編程模型,它的基礎(chǔ)思想就將業(yè)務(wù)功能構(gòu)造成一系列的服務(wù),并且能夠很好地將這些服務(wù)組合起來,達(dá)到解決業(yè)務(wù)需求的目的。在構(gòu)建這些應(yīng)用時所用到的服務(wù),不僅包含新建服務(wù),而且可以包括已有的業(yè)務(wù)應(yīng)用中的業(yè)務(wù)功能,也就是說,
SCA
提供了一套針對服務(wù)組合和服務(wù)創(chuàng)建的模型。
目前來看,雖然有很多標(biāo)榜自己是基于
SOA
的產(chǎn)品或者框架,但是大部分還是各自為戰(zhàn),而
SCA
的出現(xiàn)有望統(tǒng)一基于
SOA
思想的框架。
Apache
已經(jīng)在最近完成了
SCA
標(biāo)準(zhǔn)的實(shí)現(xiàn),各位可以去
Apache
的網(wǎng)站看看。國內(nèi)的一家
Framework
廠商普元也加入到了
OSOA
,并且也宣布會在
2007
年發(fā)布一套
SCA
框架的
Framework
。
SCA 具體的應(yīng)用目前還不太清楚,不過 IBM 的新版本 Websphere 實(shí)現(xiàn)了 SCA 0.9 標(biāo)準(zhǔn),估計(jì)慢慢地會讓 SCA 得到更廣泛的應(yīng)用。在這片文章里我想簡單談?wù)?/span> SCA 中的一些重要概念: Module,Component,ComponentType,Entry Point,External Service 。
Module
Module
是
SCA
構(gòu)架中重要的組成單元,也是粒度較粗的一個單元。
Module
在
SCA 0.9
以后版本改成了
Composite
,這可能是
OSOA
組織為了更加明確化其含義而進(jìn)行的一些命名更改。在
SCA 0.96
版本中,
Module
具有了屬性,這是為了能夠更加方便地注入給
Component
屬性值而做的調(diào)整。總之在
SCA 0.9
以及后續(xù)版本中做了一些改進(jìn),但是大體的框架沒有發(fā)生變化,如圖所表示:
它包括了
描述
Module
是通過一個
XML
格式文件進(jìn)行描述的,下面是該
XML
文件的一個大體格式:
< module? xmlns =”http://www.osoa.org/xmlns/sca/0.9”
xmlns:v ="http://www.osoa.org/xmlns/sca/values/0.9"
name ="xs:NCName" ? >
< entryPoint? name ="xs:NCName" ?multiplicity ="0..1?or?1..1?or?0..n?or?1..n" ? > *
< interface .interface-type />
< binding .binding-type?uri ="xs:anyURI" /> +
< reference > wire-target-URI </ reference >
</ entryPoint >
< component? name ="xs:NCName" > *
< implementation .implementation-type />
< properties > ?
< v:property-name > property-value </ v:property-name > +
</ properties >
< references > ?
< v:reference-name > wire-target-URI </ v:reference-name > +
</ references >
</ component >
< externalService? name ="xs:NCName" > *
< interface .interface-type /> +
< binding .binding-type?uri ="xs:anyURI" /> *
</ externalService >
< wire > *
< source .uri > wire-source-URI </ source.uri >
< target .uri > wire-target-URI </ target.uri >
</ wire >
</ module >
?
ComponentType
和
Component
對于一個
Module
內(nèi)部來說,
Component
是絕對的主力。
要說起
Component
,
ComponentType
就不得不說。
ComponentType
是一個描述
SCA
中服務(wù)的元素,它定義了服務(wù)以及服務(wù)的接口,以及服務(wù)對應(yīng)的屬性和服務(wù)引用。
ComponentType
是通過一個后綴名為
.componentType XML
文檔來描述的,描述如下:
< service? name ="MyValueService" >
< interface .java?interface ="services.myvalue.MyValueService" />
</ service >
< reference? name ="customerService" >
< interface .java?interface ="services.customer.CustomerService" />
</ reference >
< reference? name ="stockQuoteService" >
< interface .java?interface ="services.stockquote.StockQuoteService" />
</ reference >
< property? name ="currency" ?type ="xsd:string" ?default ="USD" />
</ componentType >
?
服務(wù)的接口目前分為兩種: Java interface 和 WSDL ,這很好理解, Java interface 就不說了, WSDL 想必大家也都知道,通過它的描述我們可以得到一個很準(zhǔn)確的接口。服務(wù)接口是一個可以擴(kuò)展的屬性,我們可以定義出其他不同的接口類型,當(dāng)然,前提是所使用的 SCA 必須能識別并支持才行。
服務(wù)的屬性和服務(wù)引用和
Spring
的屬性以及引用類似。
ComponentType
描述的這些屬性和引用,在
SCA Runtime
中實(shí)例化服務(wù)時,是需要注入的。屬性一般對應(yīng)的是一些簡單類型,復(fù)雜類型只能是
SDO
和
JAXB
;而引用則是需要對應(yīng)的也是一個服務(wù),在實(shí)例服務(wù)的時候,服務(wù)所引用的其他服務(wù)也需要一起實(shí)例化并注入。(注入的前提是該屬性或者引用的
requied
屬性為
true
,否則
SCA
就不會注入)。
ComponentType
只是描述性地說明一下服務(wù)的的接口以及屬性,引用,但是具體該服務(wù)對應(yīng)的實(shí)現(xiàn)以及屬性的值和引用對應(yīng)的服務(wù)是沒有給出的。
Component
就是完成上述
ComponentType
沒有完成的工作。
我們可以把
ComponentType
想象成一個
Class
,而
Component
是這個
Class
的一個
Instance
。
Component 描述了服務(wù)對應(yīng)的實(shí)現(xiàn),服務(wù)實(shí)現(xiàn)是通過 implement 元素指定的。這里要注意, SCA 中,實(shí)現(xiàn)是一個比較廣的概念,不僅僅是一個簡單的 Java 類實(shí)現(xiàn), Component 所對應(yīng)的實(shí)現(xiàn)和 ComponentType 中所定義的接口一樣,是有不同類型的。目前來看, SCA 規(guī)范中給 implement 元素定義了只給出了一個 Java 實(shí)現(xiàn): JavaImplement ,在 SCA 的一些其他擴(kuò)展信息中,提出了 BEPL 實(shí)現(xiàn)以及 EJB 實(shí)現(xiàn)等。
同樣,
Component
也描述了
ComponentType
中定義的屬性以及引用所對應(yīng)的值。
Component
的
XML
描述是在
Module
的描述文件中的,下面給出一個片段:
< implementation .implementation-type />
< properties > ?
< v:property-name? override ="no?or?may?or?must" ?
modulePropertyName ="xs:NCName" ? >
property-value
</ v:property-name > +
</ properties >
< references > ?
< v:reference-name > wire-target-URI </ v:reference-name > +
</ references >
</ component >
?
對于我們剛才提到的服務(wù)引用,這里我想羅嗦幾句。
服務(wù)引用并不是一個調(diào)用順序或者調(diào)用關(guān)系的描述,它只是指出了服務(wù)之間的引用關(guān)系,并且能夠動態(tài)注入而已。很多人認(rèn)為,
SOA
中服務(wù)和服務(wù)之間是可以通過業(yè)務(wù)規(guī)則連接起來,然后可以逐個調(diào)用,像一個
Flow
一樣,其實(shí)不然,
SOA
更重要的是關(guān)注服務(wù),比如
SCA
就很重視對服務(wù)的管理,以及將服務(wù)接口和實(shí)現(xiàn)解偶,服務(wù)和服務(wù)之間的連接也只是引用而已,并不是調(diào)用順序。用過
Seebeyond
(比較早的一個面向服務(wù)的框架,已經(jīng)被
SUN
收購)的人都知道,真正去啟動服務(wù)編排調(diào)用的還是
BEPL
。同樣
SCA
中之所以提出了
Component
的
BEPL
實(shí)現(xiàn),也是出于對服務(wù)編排調(diào)用的考慮。
EntryPoint
Module
在
SCA
中是一個粒度較為粗的單元,
Module
和
Module
之間的交互是通過定義在
Module
內(nèi)部的
Entry Point
和
External Service
進(jìn)行的,也就是說
Entry Point
是一個
Module
對外提供的接口,而
External Service
是一個
Module
對外訪問的出口。
?
Entry Point 自身是只能定義自己的訪問接口,但是真正的具體實(shí)現(xiàn)(比如一個 Java Class ),是通過它自身的 Reference 指定的。 Reference 指向的是一個 Component ,這就意味著,該 Entry Point 的調(diào)用是直接利用 Component 的實(shí)現(xiàn)來完成的。下面是 EntryPoint 的描述片段:
< interface .java?interface ="services.myvalue.MyValueService" />
< binding .ws?port ="http://www.myvalue.org/MyValueService#
wsdl.endpoint(MyValueService/MyValueServiceSOAP)" />
< reference > MyValueServiceComponent </ reference >
</ entryPoint >
?
而一個 Entry Point 既然是對外的接口,那么它就不能像我們訪問一個普通 Java 類那么去訪問了,所以在對外發(fā)布 Entry Point 是需要通過其他的一些輔助技術(shù)來完成,比如 Web Service , JMS 等,問題在于如何確定該 Entry Point 所對應(yīng)的這些輔助技術(shù)(應(yīng)該說是某種協(xié)議)呢? SCA 規(guī)定,一個 Entry Point 需要指出它的 Binding ,利用 Binding 來確定該 Entry Point 具體是需要通過什么協(xié)議來進(jìn)行發(fā)布的。
Binding
Binding
是一個可以擴(kuò)展的元素,目前
SCA 0.9
中給出了兩種
Binding: SCA, Web Service
,不過我們是可以對
Binding
進(jìn)行擴(kuò)展的,前提是所使用的
SCA
容器必須支持?jǐn)U展的
Binding
。
一旦
Entry Point
指明了自己的
Binding
后,
SCA
容器就應(yīng)該根據(jù)它所指定的
Binding
類型對它進(jìn)行對外發(fā)布。比如
Entry Point A
指定了一個
Web Service Binding
,那
SCA
就必須能將這個服務(wù)通過
Web Service
的實(shí)行發(fā)布出去(不要聯(lián)想到
UDDI
,這里的發(fā)布只是說將這個
Entry Point
制作成一個
Web Service
,能讓外界通過
Web Service
的訪問方式訪問到該
Entry Point
)。具體
SCA
如何實(shí)現(xiàn)我們不得而知。
廣告
本人的一個簡單的
SCA Container
實(shí)現(xiàn),可以在uxbalto.googlepages.com得到
相關(guān)信息,不過頁面沒怎么加,東西少得可憐。
External Service
既然理解了
Binding
,那理解
External Service
就容易許多了。先看看描述片段:
< interface .java?interface ="services.customer.CustomerService" />
< binding .sca />
</ externalService >
< externalService? name ="StockQuoteService" >
< interface .java?interface ="services.stockquote.StockQuoteService" />
< binding .ws?port ="http://www.stockquote.org/StockQuoteService#
wsdl.endpoint(StockQuoteService/StockQuoteServiceSOAP)" />
</ externalService >
?
External Service 和 Entry Point 類似,只是一個是對外發(fā)布,一個是要去遠(yuǎn)程訪問而已。我們一旦指明了 External Service 的 Binding 后,在訪問該 External Service 提供的服務(wù)時,我們就會通過指定 Binding 類型對遠(yuǎn)程發(fā)布的服務(wù)進(jìn)行訪問。
其實(shí)不難看出,由于
SCA
中
Module
和
Module
之間的交互需要通過這么一種遠(yuǎn)程發(fā)布和訪問的方式,可以認(rèn)為
Entry Point
和
External Service
之間是被調(diào)用和調(diào)用的關(guān)系,
Entry Point
發(fā)布出去的服務(wù),一般都是由
External Service
訪問的。當(dāng)然,
External Service
不一定非要去訪問
SCA
容器中的東西,單獨(dú)的非
SCA
管理的
Web Service
或者其他什么也可以利用
External Service
去訪問的。
結(jié)束語
SCA
規(guī)范中還有很多沒有在文中提起,比如異步調(diào)用,服務(wù)的
Scope,SubSystem
等,我會在以后的文章中再和大家一起討論。