Chasing an mobile web vision

          闖蕩在移動互聯網的世界中

          OSGi介紹(四)第一個bundle

          先給出“扶貧助手”的第一種改造,我稱之為“直接型”,請看:

          package aa.bb.cc;
          //需要import osgi的核心package
          import org.osgi.framework.BundleActivator;
          import org.osgi.framework.BundleContext;
          //實現了BundleActivator
          public class FamilyInfo implements BundleActivator {
           
          private String familyName;
           
          private int population;
           
          private int incomePerYear;
           省略了getter和setter方法 
           
          public String toString() {
            
            
          return "Family: " + this.familyName + ", population: " + this.population + ", income: " + this.incomePerYear;
           }

           
           
          public int getIncomePerMember(){
            
          return (int)(this.incomePerYear/this.population);
           }

           
          public static void sortByIncomePerYear(FamilyInfo[] families){
            FamilyInfo temp 
          = null;
            
          for(int i = 0; i < families.length -1; i ++){
             
          for(int j = i + 1; j < families.length; j ++){
              
              
          if(families[i].getIncomePerYear() > families[j].getIncomePerYear()){
               temp 
          = families[i];
               families[i] 
          = families[j];
               families[j] 
          = temp;
              }

             }

            }

            
           }

           
          public static void sortByIncomePerMember(FamilyInfo[] families){
            FamilyInfo temp 
          = null;
            
          for(int i = 0; i < families.length -1; i ++){
             
          for(int j = i + 1; j < families.length; j ++){
              
              
          if(families[i].getIncomePerMember() > families[j].getIncomePerMember()){
               temp 
          = families[i];
               families[i] 
          = families[j];
               families[j] 
          = temp;
              }

             }

            }

            
            
           }

           
          //在framework每次啟動該bundle的時候該方法會被framework調用執行。
           public void start(BundleContext context) throws Exception {
            FamilyInfo[] families 
          = new FamilyInfo[3];
            families[
          0= new FamilyInfo();
            families[
          0].setFamilyName("Zhang");
            families[
          0].setPopulation(3);
            families[
          0].setIncomePerYear(1200);
            families[
          1= new FamilyInfo();
            families[
          1].setFamilyName("Li");
            families[
          1].setPopulation(6);
            families[
          1].setIncomePerYear(1800);
            families[
          2= new FamilyInfo();
            families[
          2].setFamilyName("Liu");
            families[
          2].setPopulation(4);
            families[
          2].setIncomePerYear(1500);
            FamilyInfo.sortByIncomePerYear(families);
            
          for(int i = 0; i < families.length; i ++){
             System.out.println(families[i].toString());
            }

            FamilyInfo.sortByIncomePerMember(families);
            
          for(int i = 0; i < families.length; i ++){
             System.out.println(families[i].toString());
            }

           }

           
          //在framework停止該bundle時,該方法將被framework調用
           public void stop(BundleContext context) throws Exception {
           }

          }


          看到代碼的區別了嗎?我在不同之處都標注了注釋。其實,從說白了,就是實現了org.osgi.framework.BundleActivator這個接口。
          當然,細心的話,你會發現這個bundle沒有public static void main(String[] args)方法了。那么它怎么被啟動呢?這個就是bundle的奧秘所在。不過,如果你了解java的class loading機制以及reflection技術,你立馬會明白這個bundle的運行機制。這兩項技術廣泛應用于j2ee(對吧?我得承認,j2ee的經驗不多,呵呵)以及java的plugin機制。
          簡單說來,java.lang.Class這個類有一個方法:
          public Object newInstance()throws InstantiationException,IllegalAccessException
          針對上面的“扶貧助手”bundle而言,framework只要通過ClassLoader找到aa.bb.cc.FamilyInfo.class并加載后,就可以通過newInstance()方法創建一個BundleActivator的實例,然后調用public void start(BundleContext context)方法,就完成了啟動bundle的動作了。之后,調用public
          void stop(BundleContext context)方法來停止bundle
          如果你接著問,framework怎么知道這個bundle里面的BundleActivator是哪個類呢?嗯,問到點子上了。這就涉及到下面我們要講的bundle的部署了。在上一篇給出的bundle定義中指出,Jar文件是bundle的唯一格式,也就是說,我們要運行bundle,必須把代碼打成jar文件。而jar文件可以帶有manifest文件,這個文件對bundle是不可缺少的。OSGi規范里面,通過定義一系列適用于bundle的manifest關鍵字(bundle manifest header)來擴展manifest文件。
          比如,開發人員在manifest中添加下面一行:
          Bundle-Activator: aa.bb.cc.FamilyInfo
          這樣,在bundle被部署到framework后,framework就可以通過讀取manifest的關鍵字來獲得BundleActivator的具體實現類名,并通過reflection機制產生BundleActivator的實例。
          這里就給出扶貧助手的manifest的一個例子:

          Manifest-Version: 1.0  
          Bundle-SymbolicName: aa.bb.cc.family //osgi specification 4強制要求的關鍵字,每個bundle都必須有唯一的symbolic name
          Bundle-Name: Family Info Manager        //bundle的名稱
          Bundle-Version: 
          1.0   //bundle的版本號
          Bundle-Activator: aa.bb.cc.FamilyInfo   //指明BundleActivator的實現類名
          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工具,來生成bundle jar文件。這樣,第一個bundle就完成了,您可以下載一個開源的framework安裝這個bundle試一試。在framework上嘗試對該bundle的啟動和停止,輸出的結果應該和原先的java application是一樣的,然后您還可以在那個start(context)的方法中,再增加一條記錄,重新打包,然后通過framework的update功能,就能夠在不重新啟動framework的情況下升級該bundle,我就暫時偷懶不針對具體framework來給出操作的方法了,先給您自己先摸索了(當然您也可以偷懶,因為后面我會結合具體framework深入講述的)。
          好了,說完代碼的改造,再看看改造所帶來的程序設計結構變化:那~~~就~~~~是~~~~沒變化!因此我把這種原封不動的改造方法稱為“直接型”,用這種直接法,我們可以輕易的把一個java應用程序改造成bundle。而這種改造目前能看到的好處就是bundle的“熱”升級。那怎樣能更漂亮些呢?在下一篇中,我會進一步改造這個扶貧助手成為兩個bundle,看看bundle的合作將會帶來怎樣的精彩效果

          posted on 2006-02-14 15:46 勤勞的蜜蜂 閱讀(5534) 評論(4)  編輯  收藏

          評論

          # re: OSGi介紹(四)第一個bundle 2007-06-21 17:38 hata

          精彩!我看完OSGI實戰都沒想過可以用這種方式生成bundle,輪廓更清晰了,加緊看下一篇,估計更爽!哇揀到寶咯~呵呵!謝謝大哥的資料!
          還問個問題啊,你網頁中的代碼可以“+”和“-”縮進哦,是你自己做的吧?怎么實現的啊?在別的網都沒見過呢,只在IDE上用過,呵呵 :}  回復  更多評論   

          # re: OSGi介紹(四)第一個bundle 2008-01-18 23:40 風學者

          兄弟,看到這里,不得不來給你獻花.寫的很精彩,也通俗易懂,給初學者很好的指導.  回復  更多評論   

          # re: OSGi介紹(四)第一個bundle 2009-04-29 14:43 guest

          繼續

          我也正在研究,幫了不少忙,謝謝  回復  更多評論   

          # re: OSGi介紹(四)第一個bundle[未登錄] 2009-07-23 16:25 han

          我要轉載。。我要轉載。。。
          OSGI。。。。太誘人了。。  回復  更多評論   


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 鄂伦春自治旗| 余江县| 岳普湖县| 乌拉特后旗| 万安县| 靖西县| 绵阳市| 扬州市| 海城市| 报价| 达州市| 泗阳县| 湖州市| 尼勒克县| 青川县| 景宁| 麟游县| 辉南县| 墨脱县| 武乡县| 无棣县| 华阴市| 乌苏市| 红安县| 察雅县| 商洛市| 塘沽区| 全椒县| 项城市| 东兰县| 新兴县| 甘洛县| 安乡县| 弥勒县| 博白县| 乐平市| 通道| 连平县| 乐山市| 赣榆县| 南投县|