發佈和使用服務
由於 OSGi 框架能夠方便的隱藏實現類,所以對外提供接口是很自然的事情,OSGi 框架提供了服務的註冊和查詢功能。好的,那麼我們實際操作一下,就在 Hello world 工程的基礎上進行。
我們需要進行下列的步驟:
- 定義一個服務接口,並且 export 出去供其它 bundle 使用;
- 定義一個缺省的服務實現,並且隱藏它的實現;
- Bundle 啓動後,需要將服務註冊到 Equinox 框架;
- 從框架查詢這個服務,並且測試可用性。
好的,爲了達到上述要求,我們實際操作如下:
1. 定義一個新的包 osgi.test.helloworld.service
,用來存放接口。單獨一個 package 的好處是,您可以僅僅 export 這個 package 給其它 bundle 而隱藏所有的實現類
2. 在上述的包中新建接口 IHello
,提供一個簡單的字符串服務,代碼如下:
IHello
package osgi.test.helloworld.service;
public interface IHello {
/**
* 得到 hello 信息的接口 .
* @return the hello string.
*/
String getHello();
}
3. 再新建一個新的包 osgi.test.helloworld.impl
,用來存放實現類。
4. 在上述包中新建 DefaultHelloServiceImpl
類,實現上述接口:
IHello 接口實現
public class DefaultHelloServiceImpl implements IHello {
@Override
public String getHello() {
return "Hello osgi,service";
}
}
5. 註冊服務,OSGi 框架提供了兩種註冊方式,都是通過 BundleContext
類實現的:
1)registerService(String,Object,Dictionary)
註冊服務對象 object
到接口名 String
下,可以攜帶一個屬性字典Dictionary
;
2)registerService(String[],Object,Dictionary)
註冊服務對象 object
到接口名數組 String[]
下,可以攜帶一個屬性字典 Dictionary
,即一個服務對象可以按照多個接口名字註冊,因爲類可以實現多個接口;
我們使用第一種註冊方式,修改 Activator
類的 start
方法,加入註冊代碼:
public void start(BundleContext context) throws Exception {
System.out.println("hello world");
context.registerService(
IHello.class.getName(),
new DefaultHelloServiceImpl(),
null);
}
6.爲了讓我們的服務能夠被其它 bundle 使用,必須在 MANIFEST.MF 中對其進行導出聲明,雙擊 MANIFEST.MF,找到runtime > exported packages > 點擊 add,如圖,選擇 service 包即可:
選擇導出的服務包
7.另外新建一個類似於 hello world 的 bundle 叫:osgi.test.helloworld2
,用於測試 osgi.test.helloworld
bundle 提供的服務的可用性;
8.添加 import package:在第二個 bundle 的 MANIFEST.MF 文件中,找到 dependencies > Imported packages > Add …,選擇我們剛纔 export 出去的 osgi.test.helloworld.service 包:
選擇剛纔 export 出去的 osgi.test.helloworld.service 包
9. 查詢服務:同樣,OSGi 框架提供了兩種查詢服務的引用 ServiceReference
的方法:
1)getServiceReference(String)
:根據接口的名字得到服務的引用;
2)getServiceReferences(String,String)
:根據接口名和另外一個過濾器名字對應的過濾器得到服務的引用;
10. 這裏我們使用第一種查詢的方法,在 osgi.test.helloworld2
bundle 的 Activator
的 start
方法加入查詢和測試語句:
加入查詢和測試語句
public void start(BundleContext context) throws Exception {
System.out.println("hello world2");
/**
* Test hello service from bundle1.
*/
IHello hello1 =
(IHello) context.getService(
context.getServiceReference(IHello.class.getName()));
System.out.println(hello1.getHello());
}
11. 修改運行環境,因爲我們增加了一個 bundle,所以說也需要在運行配置中加入對新的 bundle 的配置信息,如下圖所示:
12. 執行,得到下列結果:
轉自:http://www.cnblogs.com/lw900320/archive/2012/06/26/2563221.html