Declarative Services――Service-Oriented Component Model
?????? Jeff 在 EclipseCon 2006 那篇介紹 Equinox 的 PPT 中提到的 Declarative Services( 文中全部采用 DS 簡稱 ) 的用法讓人極度被吸引,但同時又產(chǎn)生懷疑,想起以前自己看過 DS 好像不是這樣的,沒這么強(qiáng),便再次翻閱了 OSGI R4 中的 DS 的章節(jié),以驗證 Jeff 的說法, ^_^ ,仔細(xì)看過 DS 章節(jié)后,確實為 Declarative Services 的強(qiáng)大而感到高興, DS 是一個面向服務(wù)的組件模型,從組件模型層次上去看,它超越了傳統(tǒng)的組件模型,在組件模型描述的完備性上有了很大的進(jìn)步,例如在組件服務(wù)的依賴上、組件服務(wù)的延遲加載上、組件服務(wù)的多樣性控制上、組件服務(wù)的配置上以及組件服務(wù)的生命周期管理上,不過 DS 只能在 OSGI 容器中使用,這盡管看上去可能是個弱點,但作為 OSGI 規(guī)范中的一部分,這無可厚非,其思想值得很多目前 Component Model 的開源框架值得思考和學(xué)習(xí),如感興趣,請閱讀 OSGI R4 中 DS 章節(jié)。
簡介
?????? DS 制定的目的是為了提供發(fā)布 / 查找 / 綁定服務(wù)的模型,作為 OSGI 中的規(guī)范,它的關(guān)注和 OSGI 其他的規(guī)范一樣,都在于對于內(nèi)存的占用、代碼的大小、啟動的快速以及使用的簡易方面, ^_^ ,和一般做 java 的開源框架的那些可能不同,這也給我們帶來了不同的視角,可以看到 DS 是怎么去考慮這些方面的,在內(nèi)存的占用上, DS 采用提供組件的延遲裝載以及強(qiáng)大的組件生命周期管理的方式來控制對于內(nèi)存的占用以及啟動的快速,使用的簡易方面 DS 采用一個簡單的 xml 描述來實現(xiàn),加上它對于 Component 并沒有太多的要求,所以用起來還是比較簡單的。
Component
及其
Lifecycle
DS 作為 Service-Oriented Component Model ,雙重的體現(xiàn)出了 Component 、 Service 的概念 ( 在 DS 中其實它的準(zhǔn)確命名是 Service Component) ,一定程度上解決了以前經(jīng)常可見的所謂的 Component-Oriented 以及 Service-Oriented 的混淆概念,在 DS 中采用的為定義 Component 的方式,每個 Component 可以暴露出多個服務(wù),同時也可依賴于多個服務(wù), DS 中有三種類型的 Component ,分別為 Immediate 、 Delayed 以及 Factory ,從字面上就可以理解了,在介紹這三種類型的 Component 之前先來講講如何在 DS 中定義 Component 以及 Component Satisfied 的含義。
?????? 在 DS 中定義 Component 采用的為通過 xml 描述的方式,在 DS 章節(jié)中有關(guān)于 Component xml 描述的詳細(xì)介紹,具體可以參見該章節(jié),此 xml 描述非常的簡單, ^_^
?????? Component Satisfied 的含義非常關(guān)鍵,在 DS 中 Component 的生命周期和這個有著密切的關(guān)系,象 Component 的激活就要求 Component Satisfied ,而當(dāng) Component 在運行過程中一旦出現(xiàn) Unsatisfied 的現(xiàn)象 Component 就會被自動的注銷,那么在 DS 中 Component Satisfied 的概念到底是指什么呢? Component Satisfied 可以這么理解,它是 Component 激活的前置條件,它主要由兩點來決定是否為 Satisfied :
1、? Component 是 Enabled ;
2、? Component 的配置可被引用和解析、 Component 中引用的 Service 同樣也是 Satisfied 的,同時引用的 Service 至少有一個是處于可用狀態(tài)的,或者引用的 Service 中配置了可為 0 個可用狀態(tài) service 。
再回到三種類型的 Component ,分別看看他們的生命周期是怎么樣的:
三種類型的 Component 的啟動都依賴于 Component 處于 Satisfied 的狀態(tài)下:
Bundle 啟動時 DS 裝載相應(yīng)的配置文件 ( 通過在 mainfest.mf 中指定 Service-Component: 配置文件 ) ,解析配置文件,合并其中的組件的配置部分,獲取引用的 Service ,如上面的幾個步驟全部通過,那么 DS 就認(rèn)為這個組件是 Satisfied 的。
1、? Immediate
對于 Immediate Component , DS 會立刻激活這個 Component 。
在這個 Component 的配置文件被改動、配置信息文件 (properties 文件 ) 被改動以及所引用的 Service 被改動的情況下, DS 都會重新裝載并激活這個 Component ,同時對于引用了這個 Component 中 Service 的 Component 也會做同樣的動作。
2、? Delayed
對于 Delayed Component , DS 會根據(jù)配置文件中的 Service 的配置,注冊 Service 的信息,但此時不會激活這個 Component 。
直到這個 Component 被請求的時候 DS 才會去激活這個 Component ,相應(yīng)的設(shè)置引用的 Service 。
在這個 Component 引用的 Service 發(fā)生改變的情況下, DS 不會重新裝載這個 Component ,而會采用調(diào)用配置中設(shè)置的 bind 、 unbind 方法來重新設(shè)置引用的 Service 。
3、? Factory
Factory Component 和 Immediate Component 基本相同,不過它在激活后注冊的只是一個 ComponentFactory 服務(wù),只有在調(diào)用 ComponentFactory 的 newInstance 后才會激活里面的各個組件。
這三種類型的組件中無疑 Delayed Component 是最需要的,為系統(tǒng)的動態(tài)性帶來了很大的好處,同時也節(jié)省了內(nèi)存的占用。
組件的生命周期受 bundle 生命周期影響,當(dāng) bundle 停止時 bundle 中所有組件也就停止。
Service
的發(fā)布
/
查找
/
綁定
??????
既然是
Service-Oriented
,最為關(guān)心的當(dāng)然是
Component
中
Service
的發(fā)布
/
查找
/
綁定,分別來看看:
u??????
Service
的發(fā)布
對于
Component
中
Service
的發(fā)布,在
DS
中非常簡單就可以做到了,只需要在
Component
的
xml
中編寫如下一段:
<service>
?????? <provide interface=”net.bloajva.DemoService”/>
</service>
這樣外部的
DS
就可以引用這個
interface
的
service
了,可以看到,在這個
xml
的屬性里采用的是
interface
的聲明方式,盡管其實這個
interface
里也是允許填入實際實現(xiàn)服務(wù)接口的類名的,但不鼓勵這么做。
可以看到
Service
的發(fā)布非常的簡單,只要
Component
實現(xiàn)了相應(yīng)的
Service
的接口即可。
u??????
Service
的查找
DS
中也提供類似
jndi lookup
那樣的方式,在
Component
中可以通過定義
activate(ComponentContext context)
這樣的方法來獲得
ComponentContext
,通過
ComponentContext
就可以獲取到在
Component
配置文件里定義的引用的
Service
了。
配置文件類似這樣:
<reference name=”LOG” interface=”org.osgi.service.log.LogService”/>
代碼類似這樣:
public void activate(ComponentContext context){
?????? LogService log=(LogService)context.locateService(“LOG”);
}
^_^
,很簡單的一種方式。
u??????
Service
的綁定
DS
中提供直接綁定
service
的方法,按照
DI
的觀點來說其實就是注入
service
的支持,
DS
提供的是類似
setter
注入的方式,只是更加的強(qiáng),
^_^
,因為
DS
會根據(jù)引用的
Service
的狀態(tài)來相應(yīng)的調(diào)用這個
setter
注入,在
DS
中要采用這種方式也很簡單。
配置文件類似這樣:
<reference name=”LOG” interface=”org.osgi.service.log.LogService” bind=”setLog” unbind=”unsetLog”/>
代碼類似這樣:
public void setLog(LogService log){
?????? this.log=log;
}
public void unsetLog(){
?????? this.log=null;
}
可以看到這和目前流行的
setter DI
方式完全相同,而且更強(qiáng),
^_^
,
DS
幫忙監(jiān)聽了所引用的
Service
的生命周期狀態(tài),會根據(jù)
Service
的生命周期狀態(tài)相應(yīng)的調(diào)用
unbind
方法,連監(jiān)聽器都省了,
^_^
,后面再介紹下
Service bind
的
static reference
和
dynamic reference
的方式,那時就會發(fā)現(xiàn)它更強(qiáng)了,呵呵
這樣看下來,可以看出
DS
要實現(xiàn)現(xiàn)在的
DI
方式同樣完全是可以的,而且有更為強(qiáng)大的支持,在
DS
的情況下也是可以采用純
POJO
方式的
Component
的
(
因為象上面提到的
activate
那個方法是可以不寫的
)
,爽,對于以前用過
OSGI
中通過
ServiceRegistry
以及
ServiceReference
來發(fā)布
/
查找服務(wù)的同學(xué)們來說就會更有體會了,
^_^
更多
?????? DS
提供的不僅僅是上面所說的那些,還有很多非常強(qiáng)的功能,例如:
u??????
Component
配置
在
Spring
的
bean
的配置文件中可以引用外部的配置文件的配置信息,在
DS
中同樣可以,而且更為簡單,在
DS
中只需要在
Component
的
xml
描述文件中采用類如
property
來直接指定屬性或采用
properties
來指定引用外部的配置文件即可,而且這個配置文件的屬性在
Component
中可以通過
ComponentContext
來獲取。
u??????
Service
的
Static
、
Dynamic
引用
對于
Component
中引用的
Service
,
DS
可以采用兩種策略,一種是
static
,另外一種是
dynamic
,默認(rèn)情況下是
static
的方式,在采用
static
方式的情況下,如引用的
service
發(fā)生了變化,那么整個
Component
都會重新裝載并激活,而在
dynamic
方式的情況下,只會重新調(diào)用其中的
bind
、
unbind
方法。
在
DS
中通過在
reference
元素中增加
policy
的屬性來控制采用
static
或
dynamic
方式。
u??????
引用的
Service
的過濾
這個的含義其實在目前其他的
Component Model
中可能較少碰到,在
DS
中是支持一個
Service Interface
由多個
Component
實現(xiàn)并暴露多個實現(xiàn)的
service
的,在這種情況下可能希望只引用某種
service
的實現(xiàn),那么在
DS
中可以通過在
reference
元素中增加
target
屬性來聲明對于引用的
service
的過濾。
u??????
Cardinality
這個詞不知道該怎么翻譯好,就沒翻譯了,它里面指的主要是兩點,一個是多樣性,一個是引用的
service
的數(shù)量的控制,這點挺強(qiáng)的,
^_^..
可以通過指定
optionally
屬性值來決定引用的
service
的數(shù)目為
0
到多、
1
個、
1
到多或其他情況。
要將
Component
進(jìn)行部署非常簡單,在編寫了上面的
Component
的
xml
描述文件后,只需要在現(xiàn)在的
Bundle
中增加
Service-Component
這個屬性即可完成部署工作。
作為
OSGI
規(guī)范大家庭中的一個小部分,其可以充分利用
OSGI
規(guī)范中其他的
Service
來增強(qiáng)相應(yīng)的功能,如
Security Service
來增強(qiáng)安全性等。
對于傳統(tǒng)的
Component Model
來說,
DS
在
Component
的
Service
的發(fā)布
/
查找
/
綁定方面的機(jī)制、
Component
的生命周期管理機(jī)制、引用的
Service
的管理機(jī)制上都值得學(xué)習(xí),
^_^
目前
DS implemention
還沒有正式發(fā)布,按照
roadmap
來看的話要等到
eclipse 3.2
正式版發(fā)布后才能
release
,還得等等,
^_^
,先去
CVS
上下目前的
implemention
來用用,看看目前的
DS implemention
有多強(qiáng)了
…
posted on 2006-04-07 17:27 BlueDavy 閱讀(3414) 評論(2) 編輯 收藏 所屬分類: Java 、Plugin Architecture