在读本文之前,您应该对基于Equinox的开发有一定的了解,如果您还不太清楚,请参考基于Equinox开发HelloWorld一文。 本文讲到的例子是仿照网上甚为流行的一个例子,但苦于一直未找到源码,网上贴的都是一些转帖,代码片段,估计初学者很难将其还原并调通!我最开始弄这个咚咚的时候,其过程之痛苦,难以言喻,所以想着仿照该例子的设计,给予实现,文后贴出源码,希望能帮到大家。 该例子是一个关于计算器的实例,osgi.example.compute bundle(下文简称compute bundle)提供了统一的计算接口:Compute,另外两个bundle分别为osgi.example.compute.add(下文简称add bundle)和osgi.example.compute.multiply(下文简称multiply bundle),在这两个bundle中,各自对compute bundle进行不同的实现,一个实现加法,一个实现乘法。另外还有一个服务消费者osgi.example.compute.consumer bundle(下文简称consumer bundle),consumer bundle负责消费add bundle和multiply bundle提供的服务。上述4个bundle之间的关系如下图所示:
创建4个bundle之后的工程目录如下图所示:
通过该示例,将演示如何利用Spring DM发布和调用OSGi服务,同时还将演示OSGi的动态服务调用能力。 1. bundle osgi.example.compute compute bundle只提供一个接口——Compute,因此无需依赖更多的bundle,只需最基本的osgi即可。因为不涉及注册资源之类的,所以也无需Activator入口类。 Computer接口源代码如下所示:
add bundle是对compute bundle的具体服务实现,在MANIFEST.MF文件需要引入osgi.example.compute包;当然也可以通过添加依赖bundle的形式,即不引入包,而直接在Required Plug-ins中添加compute bundle。如下图所示:
注意:OSGi官方指出,当需要用到其他bundle的类型时,不提倡依赖bundle,应该尽可能采用Import-package的方式引入包,因为依赖bundle可能在加载bundle的时候发生问题。
通过引入osgi.example.compute包,osgi.example.compute bundle被加到了add bundl的classpath当中,解决了开发时期的类型识别问题。 这样一来,在add bundle中就能使用compute bundle中的接口了,Computer接口的实现如下:
Compute的实现已经实现了,那么如何将其发布出去呢?这个是由Spring DM负责,Spring DM利用OSGi命名空间下的<service>元素将bean导出为OSGi服务。最简单的形式为:
从示例中可以看出,beanToPublish被service元素声明导出。 另外,service结点还有一些高级属性,如depends-on、context-class-loader、ranking等待,详情请看spring dm reference。 首先,需要在add bundle的工程根目录下的”META-INF”的文件夹下创建一个文件夹,取名”spring”,Spring DM能够自动解析该文件夹下所有的spring配置文件。spring配置文件的具体内容如下所示:
该bundle和add bundle相似,在这就不赘述了。 4. bundle osgi.example.compute.client
顾名思义,该bundle将作为add 、multiply两个bundle的客户bundle,演示如何导入服务。 OSGi的测试工作比较麻烦,这方面还没研究,在这里利用spring实例化bean的时期,从构造函数入手,对服务进行测试。Client类的实现很简单,如下所示:
另外,因为client用到了其他几个bundle的类型,所以需要导入相应的包,步骤在上面已有讲到。 spring dm靠<reference>元素来引入服务,最简单的形式如下所示:
如果需要用到该服务,如某个bean包含一个com.xyz.MessageService属性,则配置该bean如下所示:
需要勾选中spring bundle版(2.5.6),spring dm的几个核心包:core、extender、io再点validate bundles按钮,校验是否已全部选中其依赖的bundle。然后即可点击运行了。 运行之后,我们发现控制台输出结果: The Sum is---11 通过ss命令,如下: 5 ACTIVE osgi.example.compute.multiply_1.0.0 6 ACTIVE osgi.example.compute.add_1.0.0 7 ACTIVE osgi.example.compute.client_1.0.0 将6停掉:stop 6 然后再refresh 7,控制台输出如下结果: The Multiply is---30 通过 ss 命令,如下: 5 ACTIVE osgi.example.compute.multiply_1.0.0 6 RESOLVED osgi.example.compute.add_1.0.0 7 ACTIVE osgi.example.compute.client_1.0.0 现在multiply处于运行状态,而add已经被停止,所以client导入的服务实际是由multiply提供的。
6. 总结
通过该文档,我们已经清楚了,如何使用Spring DM导出、导入服务。Spring DM的一些高级特性请查阅spring dm reference。 附件:osgi.example.compute.rar