`
BlueDavy
  • 浏览: 151293 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

OSGi的CM介绍和问题、模块的耦合

阅读更多

OSGi的CM就是Configuration Admin Service,是用于管理Bundle属性、并在属性发生变更时通知相应的Service,可以看出,这是保持OSGi动态性的很关键的一个服务,毕竟配置属性的修改是会发生的,象修改了Http的端口呀等,但又不希望修改这些属性后需要重启才能生效,那么CM是一个不错的选择,使用CM时无需关心属性具体怎么存储这些问题,而在属性修改后CM也会自动通知相关的service。
通常在系统的属性管理上,我们的需求通常是在一个统一的界面上对系统的相关属性进行统一的配置,保存后则希望能通知相应的服务,这里面的属性自然有些是公用的,有些是某些模块专用的,既然基于CM来实现这样的需求,首先来看看基于CM需要怎么去做,这是基于CM的统一管理系统属性的典型的序列图:
cm.PNG
其中ConfigurationAdminService、ManagedService均为CM中定义的规范的服务接口,而ConfigManageAction就是用于实现统一管理属性配置的web响应接口了,根据上图可以看出,通过调用ConfigurationAdminService的getConfiguration方法可以获取到Configuration对象,通过这个对象可以获取到配置的属性集合,而通过Configuration对象的update方法就可以更新属性了,ConfigurationAdminService在更新属性时将异步的调用系统中对外提供了ManagedService的服务的update方法,该方法的参数即为更新的属性的集合。
首先要说明下CM对于属性是怎么进行存储的,CM对于属性的存储是根据服务注册时提供的service.pid的值(必须是唯一的)以及Bundle Location(Bundle的地址)构成key来存储其属性的,按照这样的过程,在维护属性时自然也要以这个为Key来进行操作,同样的,在通知属性更新时CM也是根据这个key的值来决定的,但实现ManagedService的服务只能传入service.pid这个值,Bundle Location的值CM将自动的获取该服务所属的Bundle的Location,这看似设计的很好,但同时在应用层面则带来了一个问题,后面将会讲到。
假设我们的需求是这样的:
1、A Bundle中的PortService的port属性需要管理,BookService的bookcount属性需要配置;
2、B Bundle中的PortConfigService的port属性需要管理,MenuService中的menucount属性需要配置;
3、其中A Bundle中的PortService所需的port和B Bundle中的PortConfigService所需的port属性是相同的;
4、属性统一在C Bundle中通过提供web界面的管理方式来实现,在属性发生变化时要通知相应Bundle的Service。
那么根据上面对于CM的讲解我们来实现这个需求:
1、PortService、BookService、PortConfigService、MenuService均需实现ManagedService接口,ManagedService接口中只有一个方法update(Dictionary props),当service关注的属性被更新时CM将会自动的通知,然后服务根据属性自行的做出相应的处理;
2、PortService、BookService、PortConfigService、MenuService对外提供ManagedService接口,在注册时提供service.pid属性的值,这个值必须是唯一的,假设分别为a.port、a.bookservice、b.port、b.menuservice;
3、实现ConfigManageAction,配置页面上自然是只有port、bookcount和menucount三个属性需要配置的了,由于CM是采用service.pid加上Bundle的Location来构成key的,而在通知属性更新上也是根据这个key来决定,那么这其实也就已经意味着ConfigManageAction在管理这几个属性时必须带上相应的Bundle的Location了,这是不太合理的地方,首先要获取Bundle的Location是比较麻烦的事,其次是这样也就意味着ConfigManageAction是必须知道当属性变更时需要通知到哪些Bundle的,如果将来增加一个Bundle的服务需要监听某已经存在的属性的话,就必须要修改ConfigManageAction的代码,当然,这和注册的服务监听的server.pid的属性必须唯一也有关,也就是说CM其实只是一个基于Event的一对一的订阅/发布模型,这就导致了在维护一个port这样的公共属性的时候竟然要在A Bundle的PortService和B Bundle的PortConfigService中各存一份,OSGi联盟对于此的解释是出于安全问题的考虑,所以在CM的设计上采取了加上Bundle Location做为Key的原因。
在这样的情况下,也就导致了ConfigManageAction变得复杂了......
CM在这块设计上欠缺对于应用级属性(共享配置属性)上的考虑绝对是有待商讨的,现在只能是在各个Bundle中各自维护一套,同时在各自Bundle中提供一个ConfigManageService这样的服务来更新当前Bundle中的属性,这样才能解决Bundle Location的那个问题,在目前的情况下就没法构成共有属性的维护方式了,如果是公有属性变化的话也就只有在ConfigManageAction中调用相关的多个Bundle的ConfigManageService来完成属性的修改了,这样的话存储和动态的通知仍然交由CM去完成了。

关于模块的耦合上只有个小小的想法讨论下,就是做为设计师你能否很快的告诉别人搭建你其中的一个模块的工程需要哪几个模块的支撑,或者最好就是运行检验你其中的一个模块的功能需要哪几个模块来支撑,当然,这个在基于OSGi的系统更容易来做到,不过这个确实是设计时很关键的一个地方,这既反映了系统中模块的耦合性,更体现了系统的扩展性以及系统的组装耦合上是否合理。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics