OSGi介紹(四)第一個(gè)bundle
先給出“扶貧助手”的第一種改造,我稱之為“直接型”,請(qǐng)看:











































































































看到代碼的區(qū)別了嗎?我在不同之處都標(biāo)注了注釋。其實(shí),從說白了,就是實(shí)現(xiàn)了org.osgi.framework.BundleActivator這個(gè)接口。
當(dāng)然,細(xì)心的話,你會(huì)發(fā)現(xiàn)這個(gè)bundle沒有public static void main(String[] args)方法了。那么它怎么被啟動(dòng)呢?這個(gè)就是bundle的奧秘所在。不過,如果你了解java的class loading機(jī)制以及reflection技術(shù),你立馬會(huì)明白這個(gè)bundle的運(yùn)行機(jī)制。這兩項(xiàng)技術(shù)廣泛應(yīng)用于j2ee(對(duì)吧?我得承認(rèn),j2ee的經(jīng)驗(yàn)不多,呵呵)以及java的plugin機(jī)制。
簡(jiǎn)單說來(lái),java.lang.Class這個(gè)類有一個(gè)方法:
public Object newInstance()throws InstantiationException,IllegalAccessException
針對(duì)上面的“扶貧助手”bundle而言,framework只要通過ClassLoader找到aa.bb.cc.FamilyInfo.class并加載后,就可以通過newInstance()方法創(chuàng)建一個(gè)BundleActivator的實(shí)例,然后調(diào)用public void start(BundleContext context)方法,就完成了啟動(dòng)bundle的動(dòng)作了。之后,調(diào)用public
void stop(BundleContext context)方法來(lái)停止bundle
簡(jiǎn)單說來(lái),java.lang.Class這個(gè)類有一個(gè)方法:
public Object newInstance()throws InstantiationException,IllegalAccessException
針對(duì)上面的“扶貧助手”bundle而言,framework只要通過ClassLoader找到aa.bb.cc.FamilyInfo.class并加載后,就可以通過newInstance()方法創(chuàng)建一個(gè)BundleActivator的實(shí)例,然后調(diào)用public void start(BundleContext context)方法,就完成了啟動(dòng)bundle的動(dòng)作了。之后,調(diào)用public
void stop(BundleContext context)方法來(lái)停止bundle
如果你接著問,framework怎么知道這個(gè)bundle里面的BundleActivator是哪個(gè)類呢?嗯,問到點(diǎn)子上了。這就涉及到下面我們要講的bundle的部署了。在上一篇給出的bundle定義中指出,Jar文件是bundle的唯一格式,也就是說,我們要運(yùn)行bundle,必須把代碼打成jar文件。而jar文件可以帶有manifest文件,這個(gè)文件對(duì)bundle是不可缺少的。OSGi規(guī)范里面,通過定義一系列適用于bundle的manifest關(guān)鍵字(bundle manifest header)來(lái)擴(kuò)展manifest文件。
比如,開發(fā)人員在manifest中添加下面一行:
Bundle-Activator: aa.bb.cc.FamilyInfo
這樣,在bundle被部署到framework后,framework就可以通過讀取manifest的關(guān)鍵字來(lái)獲得BundleActivator的具體實(shí)現(xiàn)類名,并通過reflection機(jī)制產(chǎn)生BundleActivator的實(shí)例。
比如,開發(fā)人員在manifest中添加下面一行:
Bundle-Activator: aa.bb.cc.FamilyInfo
這樣,在bundle被部署到framework后,framework就可以通過讀取manifest的關(guān)鍵字來(lái)獲得BundleActivator的具體實(shí)現(xiàn)類名,并通過reflection機(jī)制產(chǎn)生BundleActivator的實(shí)例。
這里就給出扶貧助手的manifest的一個(gè)例子:
Manifest-Version: 1.0
Bundle-SymbolicName: aa.bb.cc.family //osgi specification 4強(qiáng)制要求的關(guān)鍵字,每個(gè)bundle都必須有唯一的symbolic name
Bundle-Name: Family Info Manager //bundle的名稱
Bundle-Version: 1.0 //bundle的版本號(hào)
Bundle-Activator: aa.bb.cc.FamilyInfo //指明BundleActivator的實(shí)現(xiàn)類名
Import-Package: org.osgi.framework;version=1.3 //列出該bundle需要從其他bundle所引入的
//package(s)(提供該package的bundle必須在其
//manifest中有Export-Package:
//org.osgi.framework;version=1.3)

然后我們用jdk自帶的jar工具,來(lái)生成bundle jar文件。這樣,第一個(gè)bundle就完成了,您可以下載一個(gè)開源的framework安裝這個(gè)bundle試一試。在framework上嘗試對(duì)該bundle的啟動(dòng)和停止,輸出的結(jié)果應(yīng)該和原先的java application是一樣的,然后您還可以在那個(gè)start(context)的方法中,再增加一條記錄,重新打包,然后通過framework的update功能,就能夠在不重新啟動(dòng)framework的情況下升級(jí)該bundle,我就暫時(shí)偷懶不針對(duì)具體framework來(lái)給出操作的方法了,先給您自己先摸索了(當(dāng)然您也可以偷懶,因?yàn)楹竺嫖視?huì)結(jié)合具體framework深入講述的)。










然后我們用jdk自帶的jar工具,來(lái)生成bundle jar文件。這樣,第一個(gè)bundle就完成了,您可以下載一個(gè)開源的framework安裝這個(gè)bundle試一試。在framework上嘗試對(duì)該bundle的啟動(dòng)和停止,輸出的結(jié)果應(yīng)該和原先的java application是一樣的,然后您還可以在那個(gè)start(context)的方法中,再增加一條記錄,重新打包,然后通過framework的update功能,就能夠在不重新啟動(dòng)framework的情況下升級(jí)該bundle,我就暫時(shí)偷懶不針對(duì)具體framework來(lái)給出操作的方法了,先給您自己先摸索了(當(dāng)然您也可以偷懶,因?yàn)楹竺嫖視?huì)結(jié)合具體framework深入講述的)。
好了,說完代碼的改造,再看看改造所帶來(lái)的程序設(shè)計(jì)結(jié)構(gòu)變化:那~~~就~~~~是~~~~沒變化!因此我把這種原封不動(dòng)的改造方法稱為“直接型”,用這種直接法,我們可以輕易的把一個(gè)java應(yīng)用程序改造成bundle。而這種改造目前能看到的好處就是bundle的“熱”升級(jí)。那怎樣能更漂亮些呢?在下一篇中,我會(huì)進(jìn)一步改造這個(gè)扶貧助手成為兩個(gè)bundle,看看bundle的合作將會(huì)帶來(lái)怎樣的精彩效果
posted on 2006-02-14 15:46 勤勞的蜜蜂 閱讀(5535) 評(píng)論(4) 編輯 收藏