读书人

Spring与OSGI调整 计算器例子(转) +附

发布时间: 2012-12-18 12:43:41 作者: rapoo

Spring与OSGI整合 计算器例子(转) +附整合代码和spring-osgi核心jar

开发一组计算器bundle实例

?

本节讲到的例子是仿照网上甚为流行的一个例子,但苦于一直未找到源码,网上贴的都是一些转帖,代码片段,估计初学者很难将其还原并调通!我最开始弄这个咚咚的时候,其过程之痛苦,难以言喻,所以想着仿照该例子的设计,给予实现,文后贴出源码,希望能帮到大家。
该例子是一个关于计算器的实例,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之间的关系如下图所示:

Spring与OSGI调整 计算器例子(转) +附整合代码和spring-osgi核心jar

创建4个bundle之后的工程目录如下图所示:

Spring与OSGI调整 计算器例子(转) +附整合代码和spring-osgi核心jar

通过该示例,将演示如何利用Spring DM发布和调用OSGi服务,同时还将演示OSGi的动态服务调用能力。

?

?

3.1.?bundle osgi.example.compute

?

compute bundle只提供一个接口——Compute,因此无需依赖更多的bundle,只需最基本的osgi即可。因为不涉及注册资源之类的,所以也无需Activator入口类,这个例子的四个bundles都没用用到Activator接口,实现Acitivator接口的类应该是这个bundle的开启时的入口类,而这里没用用到它,这四个bundle同样可以开启成active状态。
Computer接口源代码如下所示:

?Spring与OSGI调整 计算器例子(转) +附整合代码和spring-osgi核心jarSpring与OSGI调整 计算器例子(转) +附整合代码和spring-osgi核心jar

    ?

    ?

    通过引入osgi.example.compute包,osgi.example.compute? bundle被加到了add bundl的classpath当中,解决了开发时期的类型识别问题。
    这样一来,在add bundle中就能使用compute bundle中的接口了,Computer接口的实现如下:

    ?Spring与OSGI调整 计算器例子(转) +附整合代码和spring-osgi核心jarSpring与OSGI调整 计算器例子(转) +附整合代码和spring-osgi核心jar

      ?

      Compute的实现已经实现了,那么如何将其发布出去呢?这个是由Spring DM负责,Spring DM利用OSGi命名空间下的<service>元素将bean导出为OSGi服务。最简单的形式为:

      ?Spring与OSGI调整 计算器例子(转) +附整合代码和spring-osgi核心jarSpring与OSGI调整 计算器例子(转) +附整合代码和spring-osgi核心jar

        ?

        从示例中可以看出,beanToPublish被service元素声明导出。
        另外,service结点还有一些高级属性,如depends-on、context-class-loader、ranking等待,详情请看spring dm reference。
        首先,需要在add bundle的工程根目录下的”META-INF”的文件夹下创建一个文件夹,取名”spring”,Spring DM能够自动解析该文件夹下所有的spring配置文件。spring配置文件的具体内容如下所示:

        ?Spring与OSGI调整 计算器例子(转) +附整合代码和spring-osgi核心jarSpring与OSGI调整 计算器例子(转) +附整合代码和spring-osgi核心jar

          ?

          如此一来,其他bundle就能通过spring dm引入接口类型为osgi.example.compute.Compute的服务了,这里的osgi:service标签的id就是服务的名称,就是将bean转为服务的调用时的名称,ref为引用的是哪个bean,而interface指明只要是这个接口的定义处,都可能会用到这个服务,说可能,是因为一个接口的多个实现,也就是有多样的服务来实现,那调用时就取决于spring dm了,spring dm将通过一定的服务查找策略,返回匹配的服务。

          ?

          3.3.?bundle osgi.example.compute.multiply

          ?

          该bundle和add bundle相似,在这就不赘述了。

          ?

          3.4.?bundle osgi.example.compute.client

          ?

          顾名思义,该bundle将作为add 、multiply两个bundle的客户bundle,演示如何导入服务。
          OSGi的测试工作比较麻烦,这方面还没研究,在这里利用spring实例化bean的时期,从构造函数入手,对服务进行测试。Client类的实现很简单,如下所示:

          ?Spring与OSGI调整 计算器例子(转) +附整合代码和spring-osgi核心jarSpring与OSGI调整 计算器例子(转) +附整合代码和spring-osgi核心jar
            ?Spring与OSGI调整 计算器例子(转) +附整合代码和spring-osgi核心jarSpring与OSGI调整 计算器例子(转) +附整合代码和spring-osgi核心jar

              ?

              如果需要用到该服务,如某个bean包含一个com.xyz.MessageService属性,则配置该bean如下所示:

              ?Spring与OSGI调整 计算器例子(转) +附整合代码和spring-osgi核心jarSpring与OSGI调整 计算器例子(转) +附整合代码和spring-osgi核心jar

                ?

                reference元素还有一些高级属性,详情请见spring dm reference。
                看一下client的spring配置文件,这里用osgi:reference标签来引用服务,上面的配置中用osgi:service标签来发布服务:

                ?Spring与OSGI调整 计算器例子(转) +附整合代码和spring-osgi核心jarSpring与OSGI调整 计算器例子(转) +附整合代码和spring-osgi核心jar

                  ?

                  从上面的示例,我们可以发现,服务的导出的时候都是基于接口的,服务的引用也是基于接口的,不过spring dm支持基于类的导出、导入,但是还是建议尽量基于接口,应该记住面向接口编程的思想,以应对将来有可能发生的改变。

                  ?

                  ?

                  3.5.?运行

                  ?

                  由于add和multiply都是基于Compute接口对外导出服务,那么Client到底导入的是哪个服务呢?默认情况下,会导入启动较早的bundle服务(OSGi在bundle启动时,会为其分配一个ID值,启动越早,该值越小)。
                  运行之前,我们需要做这么一件事,搭建Spring-DM的运行环境:

                  (1)先到http://www.springsource.org/osgi上去下载Spring DM:spring-osgi-1.2.1-with-dependencies.zip,?解压后有dist和lib两个文件夹里有Spring DM运行的jar包。

                  (2)在 Package Explorer 上右击,然后点击Import --> Plug-in Development --> Plug-ins and Fragments,然后单击下一步,将弹出Import Plug-ins and Fragments 对话框,选择Directory,然后加到spring-osgi-1.2.1-with-dependencies.zip解压后的文件夹,并进入dist目录,然后点击next,将以下三个插件添加到你的“Plug-ins and Fragments to import”中:

                  ?

                  以下是引用片段:
                  ? org.springframeork.osgi.bundle.core
                  ??org.springframeork.osgi.bundle.extender
                  ??org.springframeork.osgi.bundle.io

                  ????? 现在单击完成。Eclipse会将这三个套件导入到你的工作空间中,在那里你应能够在Package Explorer视图中看到它们。

                  (3)再将spring-osgi-1.2.1-with-dependencies.zip解压包里的lib目录下导入Plug-ins and Fragments to import,选择以下插件:

                  ?

                  以下是引用片段:
                  ? org.springframeork.bundle.spring.aop
                  ??org.springframeork.bundle.spring.beans
                  ??org.springframeork.bundle.spring.context
                  ??org.springframeork.bundle.spring.core
                  ??org.springframeork.bundle.spring.jdbc
                  ??org.springframeork.bundle.spring.tx
                  ??org.springframeork.osgi.aopalliance.osgi

                  ????? 它们也加入到Package Explorer视图中。

                  ????(4)打开Run configurations,在OSGI Framework里新建一个运行平台,并将它名字改为springDM,选择四个我们写的bundles和上面导入的spring依赖bundles,然后点击Add Required Bundles,就可以添加入有依赖其它bundles而没有引入的bundle,最后点击Validate Bundles来最后确认依赖包加全了没有,提示No problems were dected.便可以运行了。

                  ?

                  (5)运行之后,我们发现控制台输出结果:
                  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提供的。

                  ?

                  ?

                  ?

                  ?

                  4.?总结

                  ?

                  通过该文档,我们已经清楚了,如何使用Spring DM导出、导入服务。Spring DM的一些高级特性请查阅spring dm reference。

读书人网 >操作系统

热点推荐