OSGi 學習之路(3) - osgi的helloworld_OSGI

來源:互聯網
上載者:User
現在可謂是萬事具備,只欠Helloworld了。為了將OSGi架構的三個層次都涵蓋到,這個Helloworld可能會比其他你見到的OSGi Helloworld程式要複雜一點點。如果對代碼中的一些API感到生疏,記得回到之前的入門篇中找到對應的內容,這樣對你理解代碼會有協助。裡面的關鍵代碼已經用黃色高亮顯示。(出於篇幅考慮,代碼中的import語句都省略) 3.1 HelloWorld的定義與實現

首先我們建立一個工程org.serc.helloworld,在這個工程裡面,我們建立一個包含sayHello方法的介面,準備作為服務介面: [java] view plain copy package org.serc.helloworld;      public interface Hello {   void sayHello();   }  

然後,對這個介面進行實現:

[java] view plain copy package org.serc.helloworld.impl;      public class HelloImpl implements Hello{   final String helloString;      public HelloImpl(String helloString){       this.helloString = helloString;   }      public void sayHello(){       System.out.println(this.helloString);   }   }  

這個類實現的sayHello所做的工作就是輸出一個在物件建構的時候得到的helloString 字串。 為了將這個介面暴露出來,我們需要在MANIFEST檔案中加入如下條目: [java] view plain copy Export-Package:  org.serc.helloworld;version="1.0"  

接下來,為了把這個服務註冊到架構中,我們定義了一個Activator: [java] view plain copy package org.serc.helloworld.activator;      public class Activator implements BundleActivator {   private List<ServiceRegistration> registrations = new ArrayList<ServiceRegistration>();      public void start(BundleContext ctx) {                               registrations.add(ctx.registerService(Hello.class.getName(),new HelloImpl("Hello, OSGi"), null));   }      public void stop(BundleContext ctx) {       for (ServiceRegistration registration : registrations) {           System.out.println("unregistering: "+ registration);           registration.unregister();       }  

我們為這個HelloImpl傳入了"Hello, OSGi"的字串 為了讓這個Activator能夠工作,需要在MANIFEST檔案中做如下定義: [java] view plain copy Bundle-Activator: org.serc.helloworld.activator.Activator  

這個bundle 最終的MANIFEST內容如下: [java] view plain copy Bundle-ManifestVersion: 2   Bundle-SymbolicName: org.serc.helloworld   Bundle-Version: 1.0   Bundle-Activator: org.serc.helloworld.activator.Activator   Import-Package: org.osgi.framework   Export-Package:  org.serc.helloworld;version="1.0"  

你的Eclipse工程中現在應該是這樣: 3.2 獲得並執行SayHello服務

建立一個工程org.serc.helloworld.client,建立一個叫HelloUser的BundleActivator,其中的start方法會獲得介面為Hello的服務物件,並且通過這個對象來調用sayHello方法: [java] view plain copy package org.serc.helloworld.client;      public class HelloUser implements BundleActivator {      public void start(BundleContext ctx) {       ServiceReference ref = ctx.getServiceReference(Hello.class.getName());       if (ref != null) {           Hello hello = null;           try {               hello = (Hello) ctx.getService(ref);               if (hello != null)                   hello.sayHello();               else                   System.out.println("Service:Hello---object null");           } catch (RuntimeException e) {               e.printStackTrace();           } finally {               ctx.ungetService(ref);               hello = null;           }       } else {           System.out.println("Service:Hello---not exists");       }   }      public void stop(BundleContext ctx) throws Exception {      }   }  

為了獲得Hello這個介面的定義,我們還需要在MANIFEST檔案中import Hello所在的package:

[html] view plain copy Bundle-ManifestVersion: 2   Bundle-SymbolicName: org.serc.helloworld.client   Bundle-Version: 1.0   Bundle-Activator: org.serc.helloworld.client.HelloUser   Import-Package: org.serc.helloworld;version="[1.0,2.0)",org.osgi.framework   3.3 HelloWorld程式的流程

可能光看代碼會比較不容易看清楚程式的執行流程,下圖表示了這幾個類的各個功能的相互依賴關係,整個關係從Hello介面的定義開始;然後到Hello介面被實現,得到HelloImpl;再到Activator將HelloImpl註冊為架構中的一個服務,再到HelloUser通過與架構互動得到剛才註冊的服務,並且使用這個服務從而輸出字串;最後一個可選流程是當我們stop org.serc.helloworld這個bundle的時候,程式會將之前註冊的服務登出掉。

  3.4 程式的執行

通過上面的工作,我們得到了兩個自己定義的bundle: org.serc.helloworldorg.serc.helloworld.client 現在開啟Run configurations介面,我們會看見Bundles標籤裡面多出來了這兩個bundle:

也就是說,OSGi架構在啟動的時候,會自動install和start這2個bundle,我們點擊Run按鈕,看看會有什麼結果: 3.5利用命令列查看程式執行過程中架構狀態的變化

3.4其實只給出了一個結果,如果你還不太清楚這個結果具體是怎麼出來的,那麼這一節的內容應該能夠協助你更好的理解輸出結果的過程。下面我們通過Equinox的一些命令列來一步一步安裝和執行bundle,並且查看過程中架構的狀態變化,來讓你們搞清楚這個結果是怎麼來的。
首先在Run configuration中取消兩個helloworldbundle的自動啟動:

然後點擊Run,這時候就不會立即輸出Hello, OSGi字串了,現在我們先用“ss”命令查看bundle的狀態:

可見兩個bundle並不是出於ACTIVE狀態,說明並沒有啟動,現在我們執行“start 8”來啟動org.serc.helloworld這個bundle:

在用services命令查看當前已經註冊的服務,我們會看到一大堆的系統服務中多出來如下一項服務:

這顯然是我們在start以後註冊上去的,但是現在還沒有任何一個bundle在使用這個服務。 接下來我們start 9號bundle,也就是我們用來調用服務的bundle:

這時就輸出了“Hello,OSGi”的字串。

那麼如果我們先啟動9號bundle而不啟動8號bundle會怎麼樣呢。大家可以試一試,因為我們在代碼中已經對沒有服務的異常情況做了處理,屆時會有相應的輸出。我們先停止8號bundle(這裡的圖中bundleID增加了,大家對號入座):

大家可以看見剛才註冊的服務已經被登出了,現在我們執行refresh 11(也就是剛才的9號bundle)來重新執行其中BundleActivator的start方法:

可見Hello服務已經不複存在了。從這裡我們可以看出來,其實Bundle的啟動順序也是一個需要注意的環節,有時候你所定義的bundle是具有順序敏感性的,必須要某些前置bundle啟動了以後,後面的bundle才能正確啟動。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.