Posted on 2006-08-16 11:58
Dart 閱讀(2097)
評論(0) 編輯 收藏 所屬分類:
SCA
1.服務屬性配置
在SCA中,服務可以定義自己的屬性,利用@Property標記即可,@Property標記具有兩個屬性參數:
1) name 屬性的名稱,一個服務中屬性名稱是唯一的,如果重復出現多次,則多出現的屬性會被忽略
2) required 表示屬性是否需要配置,它接受的是bool類型的值
@Property標記需要在我們定義的服務實現類中使用,而且需要標記在字段(Field)或者Setter方法上,這里需要注意的是,所謂的Setter方法就是我們使用的Javabean中定義的Setter方法,在SCA容器中,這種方法也是可以視為屬性。
服務屬性定義后,SCA容器在實例化服務時,會主動去初始化那些標記了@Property的字段以及方法,對于標記的字段,無論是什么樣的訪問關鍵字,甚至是private的,SCA容器也能對其進行賦植,同樣Setter方法也類似。
如果我們在Java實現類中定義屬性,可以像如下代碼中所寫那樣定義:
@Service(Service1.
class
)
public
?
class
?Service1Impl?
implements
?Service1?{
????@Property
????
private
?
int
?intValue;
?? @Property
????
public
?
void
?setIntegerValue(Integer?integerValue){
????????
this
.integerValue?
=
?integerValue;
????}
}
上面代碼中,分別是給字段以及一個方法標記了@Property,而如果我們將屬性定義寫到componentType文件中,對應上述代碼同等效應的如下所示:
<?
xml?version="1.0"?encoding="ASCII"
?>
<
sca:componentType?
xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
?xmlns:sca
="http://www.osoa.org/xmlns/sca/0.9"
>
??
<
sca:service?
name
="Service2"
>
????
<
sca:interface?
xsi:type
="sca:JavaInterface"??
????????????????????? interface="org.uxteam.sca.example.property.Service2"/>
??
</
sca:service
>
??
<
sca:property?
many
="false"
?name
="intValue"
?required
="false"
?type
="int"
?/
>
??
?
<
sca:property?
many
="false"
?name
="integerValue"
?required
="false"??
???????????????????? type="java.lang.Integer"?/>
</
sca:componentType
>
而在目前本人實現的SCA容器中,對于上面這種required值為false,并且沒有給出默認值的屬性,初始化服務實例的時候是不會將屬性設值的,如果要進行屬性設值,那需要修改上面的componentType代碼:
<?
xml?version="1.0"?encoding="ASCII"
?>
<
sca:componentType?
xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
?xmlns:sca
="http://www.osoa.org/xmlns/sca/0.9"
>
??
<
sca:service?
name
="Service2"
>
????
<
sca:interface?
xsi:type
="sca:JavaInterface"??
???????????????????? interface="org.uxteam.sca.example.property.Service2"/>
??
</
sca:service
>
??
<
sca:property?
many
="false"
?name
="intValue"
?required
="true"??
?????????????????? type="int"?default="100"/>
??
??
<
sca:property?
many
="false"
?name
="integerValue"
?required
="true"??
????????????????????? type="java.lang.Integer"?default="1234"/>
</
sca:componentType
>
這里需要注意的是,SCA規范中,對于屬性值類型有一定的限制,它規定:屬性值只能是Java的簡單基礎類型:int,short.....或者是對應的一些對象類型:Integer,String....,而對于復雜類型的值,只能是SDO類型或者是JAXB類型的。本人實現的這個容器,目前只對SDO類型做檢測,對于JAXB生成的對應并不在考慮范圍內。
服務的屬性除了可以定義單個值外,還可以將屬性值類型改成數組,或者是從Collection繼承下來的java實現類型,比如ArrayList,HashSet,LinkedList等,這一類數組以及Collection接口定義的屬性,在配置文件中的many值是為true的:
<?
xml?version="1.0"?encoding="ASCII"
?>
<
sca:componentType?
xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
?xmlns:sca
="http://www.osoa.org/xmlns/sca/0.9"
>
??
<
sca:service?
name
="Service2"
>
????
<
sca:interface?
xsi:type
="sca:JavaInterface"??
?????????????????????? interface="org.uxteam.sca.example.property.Service2"/>
??
</
sca:service
>
??
<
sca:property?
many
="true"
?name
="boolValues"
?required
="true"??
?????????????????? type="boolean"?default="false"/>
??
<
sca:property?
many
="true"
?name
="stringList"
?required
="true"??
?????????????????? type="java.lang.String"?default="firstString"/>
</
sca:componentType
>
@Service(Service1.
class
)
public
?
class
?Service1Impl?
implements
?Service1?{
????@Property
????
private
?
boolean
[]?boolValues;
????@Property
????
private
?List
<
String
>
?stringList;
????
private
?Integer?integerValue;
}
注意,如果我們想要利用List等Collection接口類型去定義many屬性,并且我們可能給出了一個默認值,這就需要我們主動去定義Collection中類型的泛型了,如同上面代碼中所寫的,stringList屬性是一個List類型的,而List放置的是String類型的對象。
就如上一次我們所提到的定義Java服務那樣,服務屬性定義也是可以從標記和配置文件中進行配置,但是如果有沖突的地方是以Java代碼標記的為主。
我們對于上面的屬性定義可以通過module文件定義它們,我本人認為在module文件中定義屬性,在初始化設置值的時候是很重要的,因為很多情況下,module配置文件才是實例化服務的一個參考標準:
<?
xml?version="1.0"?encoding="ASCII"
?>
<
sca:module?
xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
?xmlns:sca
="http://www.osoa.org/xmlns/sca/0.9"
?name
="test.module"
>
??
<
sca:component?
name
="Service1"
>
????
<
sca:implementation?
xsi:type
="sca:JavaImplementation"
?class
="org.uxteam.sca.example.property.Service1Impl"
/>
??
</
sca:component
>
??
<
sca:component?
name
="Service2"
>
????
<
sca:implementation?
xsi:type
="sca:JavaImplementation"
?class
="org.uxteam.sca.example.property.Service2"
/>
????
<
sca:properties
>
??????
<
intValue
>
100
</
intValue
>
??????
<
floatValue
>
0.01
</
floatValue
>
??????
<
doubleValue
>
0.01
</
doubleValue
>
??????
<
longValue
>
1000000
</
longValue
>
??????
<
boolValues
>
false
</
boolValues
>
??????
<
stringList
>
firstString
</
stringList
>
??????
<
integerValue
>
1234
</
integerValue
>
????
</
sca:properties
>
??
</
sca:component
>
</
sca:module
>
2.服務的引用
服務引用其實應該算是服務訪問的一種方式。
服務引用其實是指在服務實現中,通過字段或者是Setter方法去引用另外一個服務。引用是利用@Reference在Java代碼中注釋在字段或者Setter方法上定義的,或者是在componentType文件中加入<reference>元素:
@Service(TestService.
class
)
public
?
class
?TestServiceimpl?
implements
?TestService?{
????@Reference(required
=
true
)
????
private
?TestService1?a;
????
????
private
?TestService1?testService2;
????
????
public
?
void
?print()?{
????????System.out.println(
"
TestService?Print
"
);
????????testService2.print();
????}
????@Reference(required
=
true
)
????
public
?
void
?setTestService2(TestService1?testService2)?{
????????
this
.testService2?
=
?testService2;
????}
}
<?
xml?version="1.0"?encoding="ASCII"
?>
<
sca:componentType?
xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
?xmlns:sca
="http://www.osoa.org/xmlns/sca/0.9"
>
??
<
sca:service?
name
="TestService"
>
????
<
sca:interface?
xsi:type
="sca:JavaInterface"
?interface
="org.uxteam.sca.example.reference.TestService"
/>
??
</
sca:service
>
??
<
sca:reference?
name
="a"
?
>
????
<
sca:interface?
xsi:type
="sca:JavaInterface"
?interface
="org.uxteam.sca.example.reference.TestService1"
/>
??
</
sca:reference
>
??
<
sca:reference?
name
="testService2"
?
>
????
<
sca:interface?
xsi:type
="sca:JavaInterface"
?interface
="org.uxteam.sca.example.reference.TestService1"
/>
??
</
sca:reference
>
</
sca:componentType
>
@Reference具有兩個屬性:name和required,他們的作用類似于@Property屬性參數的作用。
如果定義好了@Reference,并且給出的required值為true,那SCA容器在實例化該服務的時候,會將引用服務一同實例化——盡管我們并沒有給這些字段定義值。
同@Property一樣,我們也可以將這些引用字段設為數組或者是Collection接口類型。如果將服務定義的引用體現在module文件中,是如下所寫:
<?
xml?version="1.0"?encoding="ASCII"
?>
<
sca:module?
xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
?xmlns:sca
="http://www.osoa.org/xmlns/sca/0.9"
?name
="t"
>
??
??
<
sca:component?
name
="TestService1"
>
????
<
sca:implementation?
xsi:type
="sca:JavaImplementation"
?class
="org.uxteam.sca.example.reference.TestService1Impl"
/>
??
</
sca:component
>
??
<
sca:component?
name
="TestService"
>
????
<
sca:implementation?
xsi:type
="sca:JavaImplementation"
?class
="org.uxteam.sca.example.reference.TestServiceimpl"
/>
????
<
sca:references
>
??????
<
a
>
TestService1
</
a
>
??????
<
testService2
>
TestService1
</
testService2
>
????
</
sca:references
>
??
</
sca:component
>
</
sca:module
>
從上面的文件可以看出,設置引用的時候,引用服務的值就是某個服務的name值,如果我們在設置引用的時候,并沒有將該引用類型設置為服務,在本人實現的SCA容器中,是無法對引用實例化的。
在實例化引用時,其實就是在實例化一個服務,這就會出現如下面的特殊情況:
引用出現環狀 比如A引用B,B應用了C,C又引用了A
如果是這種引用,那在沒有任何對服務生命周期管理的情況下,或者說服務都是無狀態的(關于服務的生命周期會在以后的章節中講述),也就是說,沒實例化一個服務,那它的引用也會重新實例化。
那如果在環狀引用的情況下,不難看出,會出現死循環的情況。而真對這種情況,本人實現的SCA容器會提示環狀引用的出現,并且將整個引用環的最后一個節點的引用設置為NULL
3.小結
在SCA中,服務的屬性定義和引用和Spirng的Bean管理極其相似,但是也有不同的地方。在SCA中,服務除了作為一個單獨的功能節點存在外,它和其他服務之間的引用也是很重要的,這使得服務并不是純粹意義上的獨立,服務和服務之間建立起了一定的聯系。服務屬性的定義為動態初始化服務實例提供了可能。不管是服務屬性還是服務引用,他們都是采用了依賴注入的思想,通過注入來獲得更多的靈活性和擴展性。
本人水平有限,如有錯誤的地方還請達人指點。
代碼第一部分下載
代碼第二部分下載
代碼第三部分下載