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