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