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