OSGI學習之二: HelloWorld

來源:互聯網
上載者:User

不可免俗,一律HelloWorld!

因為OSGI有三層,module,lifecycle,service,所以我們用三個helloworld來示範三個層。

1.Module Layer:

Module層沒有代碼要寫,只是將代碼打包到bundle。

比如,我們要將下邊這個類放到bundle裡。

package org.foo.hello;public class Greeting {final String m_name;public Greeting(String name) {   m_name = name;}public void sayHello() {  System.out.println("Hello, " + m_name + "!");}}

將這個類匯出到org.foo.hello.jar,並在這個jar的META-INF/MANIFEST.MF檔案裡添加

Bundle-ManifestVersion: 2
Bundle-Name: Greeting API
Bundle-SymbolicName: org.foo.hello
Bundle-Version: 1.0
Export-Package: org.foo.hello;version="1.0"

 

對於想要使用上邊建立的這個bundle的bundle,需要在它的jar包的META-INF/MANIFEST.MF裡添加

Bundle-ManifestVersion: 2
Bundle-Name: Greeting Client
Bundle-SymbolicName: org.foo.hello.client
Bundle-Version: 1.0
Import-Package: org.foo.hello;version="[1.0,2.0)"

可以看到一個是export,一個是import。

2.Lifecycle層

如果一個bundle需要做一些初始化工作,比如串連資料庫,這時lifecycle層就有用武之地了。Bundles可以頂一個 activator,這個可以讓我們介入到一個bundle的生命週期裡。這個後來會詳細再說,現在先看看這貨大概怎麼工作。下邊這個是一個單例模式的greeting類。

package org.foo.hello;public class Greeting {static Greeting instance;final String m_name;Greeting(String name) {  m_name = name;}public static Greeting get() {  return instance;}public void sayHello() {  System.out.println("Hello, " + m_name + "!");}}

它在使用前需要調用建構函式來初始化name參數。我們看一下如何利用activator來初始化:

package org.foo.hello;import org.osgi.framework.BundleActivator;import org.osgi.framework.BundleContext;public class Activator implements BundleActivator {public void start(BundleContext ctx) {  Greeting.instance = new Greeting("lifecycle");}public void stop(BundleContext ctx) {  Greeting.instance = null;}}

start和stop都是介面BundleActivator的方法,還有方法的參數BundleContext,是一個重要的參數,後面會詳細講,這貨就是你的bundle和整個OSGI系統互動用的。

這個例子就是讓你知道一個bundle可以介入自己的lifecycle,而且可以和整個OSGI framework互動。

另外你需要在你的META-INF/MANIFEST.IM裡加上

Bundle-Activator: org.foo.hello.Activator
Import-Package: org.osgi.framework

這樣OSGI framework就知道你有了自己的activator了。

3.Service層

service層是基於介面的實現方式,比如

介面:

package org.foo.hello;public interface Greeting {  void sayHello();}

OK,下邊是實現

package org.foo.hello.impl;import org.foo.hello.Greeting;public class GreetingImpl implements Greeting {final String m_name;GreetingImpl(String name) {  m_name = name;}public void sayHello() {  System.out.println("Hello, " + m_name + "!");}}

沒啥嘛,這個OSGI有個毛關係,別急,只要你平時就是面向介面編程的。改動不大,要做的就是如何註冊你的服務到OSGI,和怎樣從OSGI查詢已經註冊的服務。
所有的服務實現最終都被打包到一個bundle裡,這個bundle必須添加自己的lifecycle響應以有機會註冊自己的服務。就是說你必須實現自己的activator。LOOK:

package org.foo.hello.impl;import org.foo.hello.Greeting;import org.osgi.framework.BundleActivator;import org.osgi.framework.BundleContext;public class Activator implements BundleActivator {public void start(BundleContext ctx) {  ctx.registerService(Greeting.class.getName(),    new GreetingImpl("service"), null);}public void stop(BundleContext ctx) {}}

看看在start方法裡都幹了些什嗎?bunldecontext,註冊服務,第一個參數服務實現的介面名,接著是服務實現的執行個體,最後是service property。
stop的時候OSGI會幫你登出任何這個bundle註冊的服務。

這是註冊一個服務,那麼怎麼尋找一個服務呢?

package org.foo.hello.client;import org.foo.hello.Greeting;import org.osgi.framework.*;public class Client implements BundleActivator {public void start(BundleContext ctx) {  ServiceReference ref =  ctx.getServiceReference(Greeting.class.getName());  ((Greeting) ctx.getService(ref)).sayHello();}public void stop(BundleContext ctx) {}}

好了就這樣,這裡沒有考慮找不到服務的情況。

這裡我們可以看到得到一個service分兩步,第一步是擷取一個service的reference。用這個reference再去得服務。

 這個是因為service可以隨時被登出,你直接引用阻止jvm的記憶體回收。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.