开发一个真实的 OSGi 应用程序
我们不能只停留在 hello world 的层面,虽然那曾经对我们很重要 ,但是现实需要我们能够使用 OSGi 写出激动人心的应用程序,它能够被客户接受,被架构师认可,被程序员肯定。好的,那我们开始吧。下面将会着重介绍一些现实的应用程序可能需要的一些 OSGi 应用场景。
发布和使用服务
由于 OSGi 框架能够方便的隐藏实现类,所以对外提供接口是很自然的事情,OSGi 框架提供了服务的注册和查询功能。好的,那么我们实际操作一下,就在 Hello world 工程的基础上进行。
我们需要进行下列的步骤:
- 定义一个服务接口,并且 export 出去供其它 bundle 使用;
- 定义一个缺省的服务实现,并且隐藏它的实现;
- Bundle 启动后,需要将服务注册到 Equinox 框架;
- 从框架查询这个服务,并且测试可用性。
好的,为了达到上述要求,我们实际操作如下:
-
定义一个新的包
osgi.test.helloworld.service,用来存放接口。单独一个 package 的好处是,您可以仅仅 export 这个 package 给其它 bundle 而隐藏所有的实现类 -
在上述的包中新建接口
IHello,提供一个简单的字符串服务,代码如下:清单 2. IHello
123456789package osgi.test.helloworld.service;public interface IHello {/*** 得到 hello 信息的接口 .* @return the hello string.*/String getHello();} -
再新建一个新的包
osgi.test.helloworld.impl,用来存放实现类。 -
在上述包中新建
DefaultHelloServiceImpl类,实现上述接口:清单 3. IHello 接口实现
12345678public class DefaultHelloServiceImpl implements IHello {@Overridepublic String getHello() {return "Hello osgi,service";}} -
注册服务,OSGi 框架提供了两种注册方式,都是通过
BundleContext类实现的:-
registerService(String,Object,Dictionary)注册服务对象object到接口名String下,可以携带一个属性字典Dictionary; -
registerService(String[],Object,Dictionary)注册服务对象object到接口名数组String[]下,可以携带一个属性字典Dictionary,即一个服务对象可以按照多个接口名字注册,因为类可以实现多个接口;
我们使用第一种注册方式,修改
Activator类的start方法,加入注册代码:清单 4. 加入注册代码
123456789public void start(BundleContext context) throws Exception {System.out.println("hello world");context.registerService(IHello.class.getName(),new DefaultHelloServiceImpl(),null);} -
-
为了让我们的服务能够被其它 bundle 使用,必须在 MANIFEST.MF 中对其进行导出声明,双击 MANIFEST.MF,找到runtime > exported packages > 点击 add,如图,选择 service 包即可:
图 14. 选择导出的服务包

-
另外新建一个类似于 hello world 的 bundle 叫:
osgi.test.helloworld2,用于测试osgi.test.helloworldbundle 提供的服务的可用性; -
添加 import package:在第二个 bundle 的 MANIFEST.MF 文件中,找到 dependencies > Imported packages > Add …,选择我们刚才 export 出去的 osgi.test.helloworld.service 包:
图 15. 选择刚才 export 出去的 osgi.test.helloworld.service 包

-
查询服务:同样,OSGi 框架提供了两种查询服务的引用
ServiceReference的方法:-
getServiceReference(String):根据接口的名字得到服务的引用; -
getServiceReferences(String,String):根据接口名和另外一个过滤器名字对应的过滤器得到服务的引用;
-
-
这里我们使用第一种查询的方法,在
osgi.test.helloworld2bundle 的Activator的start方法加入查询和测试语句:清单 5. 加入查询和测试语句
1234567891011public 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());} -
修改运行环境,因为我们增加了一个 bundle,所以说也需要在运行配置中加入对新的 bundle 的配置信息,如下图所示:
图 16. 加入对新的 bundle 的配置信息

-
执行,得到下列结果:
图 17. 执行结果

恭喜您,成功了!
本文介绍了如何在OSGi框架中定义、实现并发布服务接口,同时演示了如何在其他bundle中查询并使用这些服务。
5405

被折叠的 条评论
为什么被折叠?



