前言生命周期層在OSGi框架中屬于模塊層上面的一層,它的運(yùn)作是建立在模塊層的功能之上的。生命周期層一個(gè)主要的功能就是讓你能夠從外部管理應(yīng)用或者建立能夠自我管理的應(yīng)用(或者兩者的結(jié)合),并且給了應(yīng)用本身很大的動(dòng)態(tài)性。 1 什么是生命周期管理一般來說,程序(或者程序的一部分)都一定服從某種生命周期。軟件的生命周期有4個(gè)典型的階段,如下圖:
如果你正在創(chuàng)建一個(gè)應(yīng)用,首先你得安裝(install)它;然后當(dāng)這個(gè)應(yīng)用的所有依賴都滿足了,我們就可以執(zhí)行(execute)這個(gè)應(yīng)用;如果這個(gè)應(yīng)用不需要了,我們可以停止(stop)它;過了一段時(shí)間,我們可能需要更新(update)這個(gè)應(yīng)用的版本;最后,我們可能會(huì)移除(remove)這個(gè)應(yīng)用,因?yàn)樵僖灿貌恢恕? 我們通過在外部或者內(nèi)部對(duì)應(yīng)用進(jìn)行這些操作,完成對(duì)應(yīng)用的“生命周期管理”過程。對(duì)于非模塊化應(yīng)用,這些操作就是以整個(gè)應(yīng)用為對(duì)象的;如果是對(duì)于模塊化應(yīng)用,那么我們就可以有更細(xì)粒度(針對(duì)應(yīng)用中的某個(gè)模塊)的生命周期管理了。 無論是標(biāo)準(zhǔn)的Java還是servlet,JavaEE,他們都有不同的生命周期管理機(jī)制,那么為什么我們都需要生命周期管理應(yīng)用呢? 2 為什么要管理應(yīng)用的生命周期上一章我們講解了如何通過加入metadata來完成應(yīng)用的模塊化定義,但是這些元數(shù)據(jù)中只有對(duì)bunlde靜態(tài)屬性的介紹,而并沒有提到一個(gè)應(yīng)用的動(dòng)態(tài)特征,比如某個(gè)特定的類或者對(duì)象在什么時(shí)候被需要和使用。 一般情況下,要想管理應(yīng)用的生命周期,就得通過框架提供的API來完成。一套清晰明確的生命周期API使得你的應(yīng)用可以對(duì)一段代碼進(jìn)行配置、初始化和維護(hù)。而OSGi標(biāo)準(zhǔn)就定義了這樣的一套API,使得你能在bundle生命周期的各種階段對(duì)其進(jìn)行多種外部或內(nèi)部操作,從而達(dá)到對(duì)bundle進(jìn)行功能控制的目的。 由于你構(gòu)建的應(yīng)用被模塊化為若干個(gè)部分,并且有了這些API之后你能對(duì)其中任意一個(gè)部分的去留和動(dòng)作進(jìn)行精確和即時(shí)的控制,那么你所構(gòu)建的這個(gè)應(yīng)用的靈活性就大大的提升了。如果沒有生命周期管理,別人給你什么樣的應(yīng)用,你就只能使用什么樣的應(yīng)用,可控制性很低;而一旦有了生命周期管理,無論別人給你什么樣的應(yīng)用,你也能通過生命周期管理對(duì)這個(gè)已經(jīng)模塊化應(yīng)用的行為(無論是啟動(dòng)、更新還是停止等等)進(jìn)行精確控制。把應(yīng)用每個(gè)部分都控制在自己的手中,是不是感覺非常棒? 3 OSGi bundle的生命周期模塊層的介紹中我們已經(jīng)知道如何定義一個(gè)bundle,但是要想使用bundle,就得使用生命周期層的API,和OSGi框架的生命周期層進(jìn)行交互。逐條詳細(xì)介紹API會(huì)顯得過于冗長(zhǎng)(去看看OSGi標(biāo)準(zhǔn)吧),所以接下來會(huì)通過一個(gè)例子來大致講解一下API提供給使用者的一些功能。 需要注意的是,OSGi框架的核心并沒有強(qiáng)制使用任何特定的API交互機(jī)制(比如命令行,GUI,或者XML配置文件等),只是單純的Java API而已,所以開發(fā)者可以任意創(chuàng)造出自己想要的交互模式,保證了框架的靈活性。 在標(biāo)準(zhǔn)的Java編程中,你會(huì)通過將jar包放到classpath中來使用它,而bundle則不是這樣。Bundle只有在被安裝(install)到一個(gè)OSGi框架的運(yùn)行實(shí)例中才能用起來。并且OSGi框架支持對(duì)這些bundle完整的生命周期管理,并且支持這些管理操作在應(yīng)用執(zhí)行完成,其動(dòng)態(tài)性可見一斑。 3.1 Bundle生命周期的狀態(tài)轉(zhuǎn)移圖
這個(gè)圖清晰的展現(xiàn)了bundle在生命周期中的各個(gè)狀態(tài)和狀態(tài)間的轉(zhuǎn)移條件。 3.2 框架提供的三個(gè)重要接口生命周期層的API主要是由以下三個(gè)核心接口來組成的:BundleActivator,BundleContext和Bundle。 · BundleActivator:讓你能夠捕捉bundle的start和stop事件,并對(duì)這兩個(gè)事件作出自定義的反應(yīng)。 3.2.1 BundleActivatorBundleActivator的接口是如下定義的:
如果一個(gè)類實(shí)現(xiàn)了這個(gè)接口,那么這個(gè)類就成為了一個(gè)Activator。但是有實(shí)現(xiàn)是不夠的,你要讓OSGi框架知道這個(gè)Activator的存在。所以你還需要在MANIFEST文件中添加如下一項(xiàng)屬性(假設(shè)你定義的activator的類叫做org.foo.Activator):
這樣一來,當(dāng)這個(gè)bundle啟動(dòng)(start)的時(shí)候,OSGi框架就會(huì)調(diào)用這個(gè)Activator的start方法,同樣的也適用與stop方法。 需要注意的是,并不是每個(gè)bundle都需要一個(gè)activator,有時(shí)候你的bundle只是為了和其他bundle分享代碼,而并不需要在啟動(dòng)和停止的時(shí)候做出多余的動(dòng)作,所以是否使用這個(gè)借口,還得具體問題具體分析。 3.2.2 BundleContext不知道細(xì)心的同學(xué)注意到?jīng)]有,其實(shí)在BundleActivator接口中start和stop兩個(gè)方法中,傳入的參數(shù)都是BundleContext。這個(gè)接口中的方法的功能主要分為兩個(gè)部分:
bundle context對(duì)于與其相關(guān)的bundle來說都是唯一的執(zhí)行上下文,并且只有在該bundle是屬于active狀態(tài)的時(shí)候執(zhí)行時(shí)上下文才是有意義的,對(duì)這個(gè)時(shí)段準(zhǔn)確的描述就是在start方法被調(diào)用和stop方法被調(diào)用的兩個(gè)時(shí)間點(diǎn)之間。所以如果一個(gè)bundle并沒有處于這個(gè)時(shí)間段里面,但是他的bundlecontext對(duì)象卻被使用了,那么框架就會(huì)拋出異常。 框架使用這個(gè)上下文對(duì)象還有一個(gè)目的就是為了bundle的安全和資源分配,所以BundleContext對(duì)象應(yīng)該被當(dāng)做私有對(duì)象,不應(yīng)該被隨意在bundle之間傳遞。 3.2.3 Bundle在BundleContext接口中,我們發(fā)現(xiàn)有名為getBundle的方法,我們可以從中得到Bundle對(duì)象。 對(duì)于每個(gè)被安裝到框架中的bundle,框架都創(chuàng)建了一個(gè)Bundle對(duì)象在邏輯上表達(dá)之。這個(gè)接口中定義了bundle生命周期管理的方法,下面是這個(gè)接口的片段,這個(gè)接口的方法所帶來的功能都是顯而易見的:
稍微需要說明一下的是getLocation方法,大部分OSGi框架的實(shí)現(xiàn)都是將locatioin解釋為指向OSGi bundle的一個(gè)URL,在需要的時(shí)候就會(huì)通過URL將bundle下載到框架中來安裝使用。但是OSGi標(biāo)準(zhǔn)沒有規(guī)定location的形式必須是URL,而且URL也并不是非要不可的,因?yàn)槲覀冞€可以通過輸入流(Input Stream)來安裝bundle。 此外,bundle不能自己改變自己的狀態(tài),比如說一個(gè)active的bundle不能stop自己,stop自己就會(huì)拋出異常。 4 總結(jié)繼模塊層之后,我們又介紹了OSGi的模塊層,這里主要是介紹了一些核心接口,具體的使用示例依然會(huì)在《OSGi開發(fā)環(huán)境的建立和HelloWorld》中為大家展示。這一章的內(nèi)容依然是比較基礎(chǔ)的,其中還有很多的細(xì)節(jié)和更加深入的內(nèi)容沒有在這里提出來,那些內(nèi)容將在進(jìn)階篇中為大家講解。 |
|
|