继续以OSGI R4的Declarative Services(DS)来讲讲Service-Oriented Component Model(SOCM),SOCM对于现有的Component-Oriented Model或者是Service-Oriented Model来说到底有什么不同的地方,到底DS能给我们带来什么样的好处呢?
首先来看看SOCM的概念,Component-Oriented Model、Service-Oriented Model曾经风行过很长一段时间,现在Component-Oriented Model听得更少了,Service-Oriented Model则在如今的SOA中体现的淋漓尽致了,那么为什么会有SOCM这样的概念冒出来呢,其实SOCM并不是DS提出来的,DS也是从Gravity中学习过来的,Component-Oriented Model强调的是系统以component方式的一种复用,而Service-Oriented Model强调的是系统以一种服务的方式来完成系统功能的实现,而SOCM则强调两者,SOCM认为Component是Service的提供者,一个Component可以提供0至多个Service,其实这样的概念放到SOA中仍然是可行的,同样可以认为SOA也是一种SOCM,当然,DS的目的和SOA是不同的,所以表现出来两者并无重复,而且作为SOCM来说DS的表现则更为优秀一些。
在了解了SOCM的概念后,来看看DS提出的目的,DS提出的目的其实强调的是对于Service Dependency的动态管理的实现,而在SOA中更在乎的是Service的动态Dependency的实现,但不是管理,这和DS是不同的,DS作为OSGI R4的一部分,自然要继承OSGI本身的理念,就是系统足够的动态化,DS强调自己是一种context-aware architecture,为什么这么说呢,这个在后面会讲到。
讲讲OSGI R4为什么要引入DS呢,OSGI自己本身其实就是一种SOCM,它的Activator就代表着Component,而在这个Component中可以通过BundleContext进行Service的发布/查找/绑定,同样的实现了SOCM,那它为什么还要引入DS呢?如果你使用过OSGI来进行系统的实现,就会知道通过Activator来完成Service的发布/查找/绑定是多么麻烦的一件事情,更关键的是还得监听服务的状态,以便根据服务的状态对Component做出适当的行为,如果忘记根据依赖的服务的状态进行处理,系统很容易出现某个Component不可用甚至造成系统崩溃的现象,DS的提出就是为了解决这个麻烦的,DS允许将任何一个POJO定义为Component,这样就不用只通过Activator来完成Service Dependency的设置了,同时DS会帮忙根据Component所依赖的服务的状态来决定Component的生命周期,而不用自己去处理这个问题,而且DS还能帮助完成Component中Service Dependency的动态管理,如根据Service的状态自动绑定或注销Service、自动的替换Service等,而这所以的自动化的管理依赖的都是系统运行的context,而不是通过应用去管理。
其实象现在的Spring IoC Container可以看作是一种Component-Oriented Model的支持,它解决了其中Component之间依赖的实现,但至于Component之间依赖的动态管理(例如Component根据其所依赖的Component的动态生命周期管理等),暂时还没有什么支持,在SOA中同样也是如此,这就造成了如果要对系统进行调整,就必须在静态配置阶段完成,而不能在系统运行时进行动态的调整,也不能根据系统目前运行的状态来自动的对Component、Service的Dependency进行管理,而在DS中这些都是可以做到的,所以DS强调自己是一种Context-aware architecture,也就是说它可以根据上下文来动态的对Component的生命周期进行管理、动态的对Service Dependency进行管理,^_^,智能化的管理系统。
简单的说说在DS中DI的使用方式以及Service Dependency的动态管理的一些策略:
DI的使用方式
在前面的一篇blog中已经有提及了,在DS中可以采用lookup或类似setter DI这样的方式来完成service的注入。
Service Dependency的动态管理
通过设置Service Dependency的policy、target、cardinality来实现动态的管理,例如policy就控制了是否根据所依赖的服务的状态来管理Component的生命周期,如果设置为static,在所依赖的service变得不可用的情况下,DS就会自动的将这个Component的状态设置为不可用,同时自动的处理依赖于这个Component所提供的Service的那些Component,target则是针对在DS中允许出现实现同一接口的多种实现的过滤策略,可以通过target准确的找到自己想要的service的实现,cardinality就指明了所依赖的是多少个服务接口的实现,也就是说允许使用一个接口的多种实现,^_^,在系统运行时,如Component所依赖的服务变得可用了了,那么DS会自动将这个Component的状态设置为statisfied,这个时候如果外部有调用到这个component,那么component就被真正的实例化(这是对于lazy性质的Component而言),当Component所依赖的服务变得不可用时,DS会尝试寻找系统中是否仍然有可用的所依赖的服务(因为在DS中一个服务接口是可能有多个实现的),如果找到DS则重新设定,如没找到DS则会将Component的状态重新设置为unstatisfied,同时通知引用了这个component提供的service的那些component。
经过这样一些说明,可以看出DS主要强调的是动态的Service Dependency的管理,而不仅仅是之前业界流行并已经得到认可的DI,Service Dependency的管理为系统带来了很大的灵活性,使得系统自身可以根据系统运行的context做出相应的响应,不过正因为这个原因,我们也不难发现这给测试工作带来了更大的复杂度,测试时需要更多的模拟出系统的运行状态,DS另一方面则给我们带来了动态替换系统实现的好处,另外,我觉得的好处就是依托于OSGI这样一个plugin architecture上,它使得面向接口的编程更加的突出和得以强制。