Felix動(dòng)態(tài)化的試驗(yàn)
在動(dòng)態(tài)化方面,最為關(guān)心的是Felix在“即插即用”、“熱部署”以及“即刪即無(wú)”三點(diǎn)上的表現(xiàn),這三點(diǎn)涉及到的主要是引用對(duì)象的遷移以及對(duì)象狀態(tài)的保留,而對(duì)于OSGi的應(yīng)用,引用對(duì)象的遷移涉及到的為package依賴(lài)以及OSGi服務(wù)依賴(lài)的遷移,在對(duì)象狀態(tài)的保留上,OSGi不提供支持,為了更方便的觀察Felix在動(dòng)態(tài)化的表現(xiàn),在程序中直接啟動(dòng)Felix,通過(guò)這樣的方式獲取到BundleContext,進(jìn)而調(diào)用Bundle中OSGi服務(wù)的方法來(lái)檢測(cè)package依賴(lài)、OSGi服務(wù)依賴(lài)在“即插即用” 、“熱部署”以及“即刪即無(wú)”這三種情況下的變化情況,在程序中啟動(dòng)Felix的代碼片段如下:
FrameworkFactory factory=new FrameworkFactory();
Properties startProps=new Properties();
startProps.put("felix.auto.start.1", "file:bundle/org.apache.felix.scr-1.0.8.jar
file:bundle/org.apache.felix.shell-1.2.0.jar
file:bundle/org.apache.felix.shell.tui-1.2.0.jar
file:bundle/org.apache.felix.bundlerepository-1.4.0.jar");
List list = new ArrayList();
list.add(new AutoActivator(startProps));
startProps.put(FelixConstants.SYSTEMBUNDLE_ACTIVATORS_PROP, list);
startProps.put("felix.log.level", "1");
startProps.put("osgi.shell.telnet", "on");
Framework framework=factory.newFramework(startProps);
framework.start();
context=framework.getBundleContext();
l 即插即用
即插即用是硬件體系中宣傳的最多的一項(xiàng),例如USB硬件等,對(duì)于OSGi的應(yīng)用,此時(shí)期待的是安裝上新的Bundle后,此新Bundle的功能即可正常使用。
從package依賴(lài)和服務(wù)依賴(lài)兩個(gè)角度來(lái)看,假設(shè)A Bundle對(duì)外提供了HotDeployDemoService實(shí)現(xiàn),此實(shí)現(xiàn)依賴(lài)了B Bundle對(duì)外export的org.osgichina.domain的package以及D Bundle對(duì)外export的org.osgichina.hotdeploy.service的package,實(shí)現(xiàn)還需要調(diào)用DBService,此OSGi
Service由C Bundle對(duì)外提供,C Bundle也依賴(lài)于D Bundle export的DBService的接口package,同時(shí)此實(shí)現(xiàn)采用了一個(gè)計(jì)數(shù)器來(lái)計(jì)數(shù)執(zhí)行的次數(shù),代碼片段如下: A Bundle public class DemoComponent implements DemoService { private AtomicInteger count=new AtomicInteger(0); private DBService dbservice; public void setDBService(DBService dbservice){ this.dbservice=dbservice; } public void unsetDBService(DBService dbservice){ if(this.dbservice==dbservice){ this.dbservice=null; } } /* (non-Javadoc) * @see
org.osgichina.hotdeploy.demo.service.DemoService#execute() */ @Override public void execute() { System.out.println("execute times:"+(count.incrementAndGet())); User user=new User(); dbservice.execute(user.getName()); } } B Bundle public class User { public String getName(){ return "bluedavy"; } } C Bundle public class DBComponent implements DBService { @Override public void execute(String username) { System.out.println("execute
DBComponent,username is:"+username); } } 通過(guò)程序在外部啟動(dòng)Felix,每5秒鐘執(zhí)行下DemoService的execute方法,啟動(dòng)完畢后,首先安裝上A Bundle,此時(shí)由于A Bundle缺少了所依賴(lài)的package以及OSGi服務(wù),其需要對(duì)外提供的OSGi服務(wù)必然也無(wú)法激活,因此console輸出了以下信息: 未找到需要調(diào)用的服務(wù) 安裝并啟動(dòng)B Bundle和DBundle,嘗試啟動(dòng)A Bundle,Console仍然輸出: 未找到需要調(diào)用的服務(wù) 繼續(xù)安裝并啟動(dòng)C
Bundle,嘗試啟動(dòng)A Bundle,Console輸出: execute times:1 execute DBComponent,username is:bluedavy 從上可見(jiàn),在Felix中要達(dá)到即插即用的效果還是非常容易的,只要安裝并啟動(dòng)了所依賴(lài)的package(BBundle、DBundle)和OSGi服務(wù)所在的Bundle(CBundle)后,再行啟動(dòng)依賴(lài)這些package和OSGi 服務(wù)的Bundle(ABundle),那么新安裝的Bundle的功能就可被使用,效果也稱(chēng)得上是即插即用了。 l 熱部署 熱部署期待的效果是直接覆蓋需要更新的jar,所有新的請(qǐng)求都會(huì)自動(dòng)執(zhí)行到新的代碼中,且保留更新的對(duì)象的狀態(tài)。 仍然采用即插即用中的例子,分別來(lái)看看當(dāng)B Bundle和C Bundle更新時(shí)A Bundle服務(wù)執(zhí)行的狀況,將B Bundle的getName修改為return “osgi”;,覆蓋B Bundle,執(zhí)行update后,觀察console的輸出: execute times:23 execute DBComponent,username is:bluedavy 從此可見(jiàn),update后B Bundle的修改并沒(méi)生效,嘗試執(zhí)行下refresh后,繼續(xù)觀察console的輸出: execute times:1 execute DBComponent,username is:osgi 可以看到,此時(shí)B
Bundle的修改已生效,但伴隨的是execute times這個(gè)對(duì)象狀態(tài)的重置。 繼續(xù)修改C Bundle,將C Bundle打印的信息改為,execute
new DBComponent,修改完畢后覆蓋C Bundle,執(zhí)行update后,觀察console的輸出: execute times:1 execute new DBComponent,username is:osgi 可見(jiàn)C Bundle的修改立刻生效了,但同樣伴隨著的是execute times這個(gè)對(duì)象狀態(tài)的重置。 按照如上的試驗(yàn),在使用Felix的情況下,如要更新其他Bundle依賴(lài)的package的Bundle,需要采用的步驟為:覆蓋bundle文件àupdate
bundleàrefresh,;如要更新其他Bundle需要調(diào)用的OSGi服務(wù)的Bundle,需要采用的步驟為:覆蓋bundle文件àupdate bundle;但兩者伴隨著的都是更新的Bundle以及依賴(lài)(遞歸)了其的Bundle中的對(duì)象狀態(tài)的丟失,可見(jiàn),要想基于Felix就直接得到熱部署的效果還是做不到的,需要在Felix的基礎(chǔ)上自行做一定的擴(kuò)展。 l 即刪即無(wú) 即刪即無(wú)期望的效果是在停止Bundle后,其所對(duì)外export的package以及OSGi Service都不再可用,仍然采用即插即用中的例子進(jìn)行測(cè)試。 首先來(lái)看看停止B
Bundle后,觀察console的輸出: execute times:168 execute new DBComponent,username is:osgi 可見(jiàn),這么做并不會(huì)影響A
Bundle使用B Bundle export的package,那么嘗試使用uninstall B Bundle,這下行了吧,滿(mǎn)心期待的觀察console的輸出: execute times:185 execute new DBComponent,username is:osgi 居然仍然可以使用,看來(lái)只能再?lài)L試下refresh了,繼續(xù)觀察console的輸出: 未找到需要調(diào)用的服務(wù) 恩,這才是期待的效果,說(shuō)明此方法可行。 繼續(xù)安裝上B Bundle,來(lái)看下停止C
Bundle后,console的輸出: 未找到需要調(diào)用的服務(wù) 恩,正如期待的效果,說(shuō)明此方法可行。
posted on 2009-05-25 22:58 BlueDavy 閱讀(5354) 評(píng)論(4) 編輯 收藏 所屬分類(lèi): OSGi、SOA、SCA