SCA程序設(shè)計(jì)——本地服務(wù)的定義以及使用
Posted on 2006-08-11 14:23 Dart 閱讀(1831) 評(píng)論(9) 編輯 收藏 所屬分類: SCA1.?????? SCA 簡(jiǎn)介
“
2005
年
11
月,
IBM
、
BEA
、
Oracle
、
SAP
等國(guó)外著名企業(yè)聯(lián)合發(fā)布了
SCA 0.9
規(guī)范草稿。
SCA
是一種全新的、跟語(yǔ)言無(wú)關(guān)的編程模型,這種面向服務(wù)構(gòu)件的編程模型可以大大簡(jiǎn)化客戶的編程,提高應(yīng)用的靈活性,將會(huì)對(duì)現(xiàn)有軟件開(kāi)發(fā)方式產(chǎn)生顛覆性的影響。”上面段文字是摘自普元
SCA
中文論壇中對(duì)
SCA
的描述,大家可以通過(guò)上面簡(jiǎn)短的文字對(duì)
SCA
有一個(gè)簡(jiǎn)單的認(rèn)識(shí)。
SCA
全稱
Service Component Architecture
(服務(wù)組件構(gòu)架)
,
它是一套遵循
SOA
思想的構(gòu)架,通過(guò)模型描述來(lái)構(gòu)建應(yīng)用系統(tǒng)。
SCA
并不只是針對(duì)于一種語(yǔ)言,它是可以支持多種語(yǔ)言的(
Java,C++,PHP….
),目前
SCA
給出了
Java
以及
C++
的實(shí)現(xiàn)規(guī)范。
對(duì)于 Java 版本的 SCA ,可以通過(guò)配置文件以及 J2SE5.0 的 Annotation 功能來(lái)描述服務(wù),或者是通過(guò) XML 格式的配置文件來(lái)描述服務(wù),并能使得 SCA 容器對(duì)其進(jìn)行管理。
以下文中所提到了
SCA
都是
Java
版本的
SCA
。
SCA
中的服務(wù)可以分為本地、遠(yuǎn)程服務(wù),以及外部服務(wù),服務(wù)具有自己的屬性、引用,并且通過(guò)一些表示,可以確定服務(wù)的生命周期。
下面介紹一下如何定義本地服務(wù),以及如何去調(diào)用本地服務(wù)。
2
.簡(jiǎn)單的本地服務(wù)
SCA
中可以通過(guò)
J2SE5.0
的
Annotation
來(lái)對(duì)服務(wù)進(jìn)行標(biāo)記,利用
@Service
標(biāo)簽,就可以定義一個(gè)服務(wù),一般情況下,服務(wù)一般是一個(gè)接口類,服務(wù)實(shí)現(xiàn)是一個(gè)具體實(shí)現(xiàn)該接口的類,當(dāng)然,我們也可以把一個(gè)具體的類定義為一個(gè)服務(wù),服務(wù)實(shí)現(xiàn)即其本身。
@Service
標(biāo)記是放在實(shí)現(xiàn)類上使用的,當(dāng)標(biāo)記上后,
SCA
容器就會(huì)認(rèn)為這個(gè)實(shí)現(xiàn)類為服務(wù)的實(shí)現(xiàn)。而服務(wù)的描述則是通過(guò)
@Service
的值來(lái)指定的,請(qǐng)看下面代碼:
public ? class ?TestServiceImpl? implements ?TestService?{
???? public ? void ?invoke()?{
????????System.out.println( " invoke?method " );
????}
???? public ? void ?print(String?printString)?{
????????System.out.println( " print? " ? + ?printString?);
????}
}
上面代碼的將
TestServiceImpl
上標(biāo)記了
@Service
,而@Service中的TestService.class值就表明了該服務(wù)接口即為TestService接口,而TestServiceImpl就是這個(gè)服務(wù)的實(shí)現(xiàn)。通過(guò)上面簡(jiǎn)單的定義,一個(gè)簡(jiǎn)單的本地服務(wù)就算是做好了。
這是最簡(jiǎn)單的本地服務(wù)例子, @Service 中的服務(wù)接口僅僅只有一個(gè),如果我們想要去調(diào)用這個(gè)服務(wù)則需要啟動(dòng) SCA 容器,然后通過(guò)模型上下文去定位服務(wù):
??????? ??????
??????????????sca.start();?
??????????????TestService?service? = ?(TestService)CurrentModuleContext.getContext().locateService( " TestService " );?
??????????????service.invoke();?
??????????????service.print( " print?it " );?
簡(jiǎn)單說(shuō)一下上面代碼。
SCA 是 OSOA 組織提供的 SCA 框架標(biāo)準(zhǔn)接口,它初始化后會(huì)將當(dāng)前線程中的模塊上下文( ModuleContext ,也是 SCA 的一個(gè)標(biāo)注接口)賦值,用戶可以通過(guò) CurrentModuleContext 類的靜態(tài)方法去獲得這個(gè) ModuleContext ,模塊上下文實(shí)例就可以去通過(guò)服務(wù)名定位這個(gè)服務(wù)。
我們通過(guò)
Annotation
標(biāo)記服務(wù)的時(shí)候是不能給出服務(wù)名的,這種標(biāo)記方式會(huì)將服務(wù)接口名默認(rèn)為服務(wù)名。
?
3 .多個(gè)服務(wù)接口
在上面我們使用的 @Service 的值只有一個(gè),其實(shí) @Service 可以定義多個(gè)服務(wù)接口,形式如下: @Service(interfaces={Interface1.class,Interfaces2.class.....}) ,這種描述方式可以一次性定義多個(gè)服務(wù),當(dāng)然了,服務(wù)實(shí)現(xiàn)也還只是一個(gè)而已。
下面代碼展示了如果定義多個(gè)服務(wù):
public ? class ?TestServiceImpl1? implements ?TestService1?,?TestService2?{?
??
??????? public ? void ?invoke()?{?
??????????????System.out.println( " example2?invoke?method " );?
???????}?
??
??????? public ? void ?print(String?printString)?{?
??????????????System.out.println( " print? " ? + ?printString?);?
???????}?
??
}?
這種標(biāo)記的話,
SCA
容器就會(huì)識(shí)別出
2
個(gè)服務(wù):
TesrService1
和
TestService2
:
????????????
??TestService1?service1? = ?(TestService1)?context.locateService( " TestService1 " );?
??????????????service1.print( " print?it " );?
? TestService2?service2? = ?(TestService2)?context.locateService( " TestService2 " );?
??????????????service2.invoke();?
如果我們?cè)诙x服務(wù)的時(shí)候,出現(xiàn)了服務(wù)定義和服務(wù)實(shí)現(xiàn)不一致,那就會(huì)出現(xiàn)異常。
注意:這里的異常并不是
SCA
標(biāo)準(zhǔn)中所提到的,因?yàn)?/span>
SCA
只給出了規(guī)范,很多廠商的實(shí)現(xiàn)都不太一樣,對(duì)于上述問(wèn)題的處理可能也不一樣。在以后的章節(jié)文章中,還會(huì)出現(xiàn)一些這種情況,在
SCA
標(biāo)準(zhǔn)沒(méi)有明確指明的情況下,我都是以個(gè)人的實(shí)現(xiàn)來(lái)處理的,待
SCA
完善后再進(jìn)行標(biāo)準(zhǔn)處理。對(duì)于上面情況,我在實(shí)現(xiàn)這個(gè)簡(jiǎn)單的
SCA
容器時(shí),將這個(gè)情況看成是異常:
public ? class ?TestServiceImpl2? implements ?TestService1??{?
??
??????? public ? void ?print(String?printString)?{?
??????????????System.out.println( " example2?print? " ? + ?printString?);?
???????}?
??
}?
?以下調(diào)用方式會(huì)出現(xiàn)異常:
??????????????service3.invoke();?
4
.通過(guò)配置文件來(lái)生命服務(wù)以及實(shí)現(xiàn)
SCA 中可以根據(jù)配置文件來(lái)對(duì)服務(wù)進(jìn)行描述。
描述服務(wù)接口的是一個(gè)后綴名為
componentType
的
XML
文件,下面我們給出一個(gè)簡(jiǎn)單的例子:
< componentType? xmlns ="http://www.osoa.org/xmlns/sca/0.9" > ?
< service? name ="TestService3" > ?
< interface .java?interface ="org.uxteam.sca.example3.TestService3" /> ?
</ service > ?
< service? name ="TestService4" > ?
< interface .java?interface ="org.uxteam.sca.example3.TestService4" /> ?
</ service > ?
</ componentType > ?
上面的這個(gè)
XML
指明了服務(wù)的名稱以及服務(wù)對(duì)應(yīng)的接口類:
第一個(gè)服務(wù)為
TestService3
,對(duì)應(yīng)得是一個(gè)
Java
接口,接口類得全路徑是
org.uxteam.sca.example3.TestService3
第二個(gè)服務(wù)為
TestService4
,對(duì)應(yīng)的是一個(gè)
Java
接口,類路徑為
org.uxteam.sca.example3.TestService4
一般情況下,該“組件描述”文件是和實(shí)現(xiàn)類放在一個(gè)目錄下的,文件名同實(shí)現(xiàn)類文件名相同,只是后綴名改為
componentType
。
componentType
文件只是描述了服務(wù)接口,但是服務(wù)實(shí)現(xiàn)并沒(méi)有給出。
其實(shí)服務(wù)實(shí)現(xiàn)的描述是在
.module
文件中給出的。
.module
文件指明在
componentType
文件中給出的服務(wù)接口的實(shí)現(xiàn)類,如下:
< module? xmlns ="http://www.osoa.org/xmlns/sca/0.9" ?
name ="scaexample" ? > ?
< component? name ="TestService3" > ?
< implementation .java?class ="org.uxteam.sca.example3.TestServiceImpl" /> ?
</ component > ?
??
< component? name ="TestService4" > ?
< implementation .java?class ="org.uxteam.sca.example3.TestServiceImpl" /> ?
</ component > ?
</ module > ?
這個(gè)文件中,將服務(wù)名和組件名對(duì)應(yīng)了起來(lái),比如第一個(gè)組件是
TestService3
,它是一個(gè)
Java
實(shí)現(xiàn),并且類路徑是
org.uxteam.sca.example3.TestServiceImpl
。同理,第二個(gè)組件也如此。
我在實(shí)現(xiàn)這個(gè)簡(jiǎn)單的
SCA
容器時(shí)規(guī)定,
module
文件必須放置在
bin
目錄下(當(dāng)然,其他的
SCA
容器如何規(guī)定我就不得而知了)
當(dāng)
SCA
容器啟動(dòng)得時(shí)候,會(huì)去解析這幾個(gè)文件,如果文件無(wú)誤,那
SCA
就會(huì)開(kāi)始維護(hù)配置文件中定義得服務(wù)了。我們同樣可以去定位、調(diào)用這些服務(wù):
?????????????
????????????sca.start();?
????????????ModuleContext?context? = ?CurrentModuleContext.getContext();?
????????????TestService3?service? = ?(TestService3)context.locateService( " TestService3 " );?
????????????service.invoke();?
??????????????
???????????TestService4?service1? = ?(TestService4)context.locateService( " TestService4 " );?
???????????service1.execute();?
5
.結(jié)束語(yǔ)
通過(guò)上面的介紹希望能讓網(wǎng)友們對(duì)
SCA
有一個(gè)比較清晰簡(jiǎn)單的認(rèn)識(shí)。而本人實(shí)現(xiàn)的
SCA
容器目前來(lái)說(shuō)還很幼稚,我會(huì)隨著對(duì)該
SCA
文章的更新來(lái)完善我的
SCA
容器。我本人希望能借此文章拋磚引玉,各位達(dá)人請(qǐng)多多指點(diǎn),有錯(cuò)誤的地方還請(qǐng)大家指正。