`

OSGI中的service依赖关系管理

    博客分类:
  • OSGI
阅读更多


    众所周知,对于高动态高可扩展的应用,OSGI是一个非常好的平台。但是,也因此增加了复杂性,开发中对service的依赖变得复杂。这也是service的关系管理成为OSGI中一个非常重要的部分,我们来看看OSGI中service依赖关系管理的方式。篇幅原因,只关注发展历程,不具体介绍每个方式的详细实现细节。

    概括的说,目前在OSGI中主要有以下几种service依赖关系管理的方法:

    1. Service listener
    2. Service binder
    3. Dependency Manager
    4. Declarative Services
    5. iPOJO
    6. blueprint
   
1) Service Listener

    这是OSGI中原生的service依赖管理机制,是最简单直接的方式,其基本原理非常简单,标准的注册/查找:
   
    1. 被依赖的bundle通过BundleContext.registerService()方法注册服务到系统中
    2. 使用依赖的bundle在start时通过BundleContext的getServiceReferences()/getService()来查找依赖的service
    3. 使用依赖bundle通过BundleContext.addServiceListener()来分别注册ServiceListener
    4. 在被依赖的bundle/service状态发生变化时, 使用依赖bundle通过ServiceListener的serviceChanged()得到通知并作出调整。

    在这种方法中,使用依赖的Service必须进行大量的编码工作来完成对依赖的service的关系管理,需要处理琐碎细节如各个Service的运行时状态变化。为了减少工作量,OSGI设计了ServiceTracker来简化对依赖service的编码工作,即ServiceTracker将负责处理上述步骤中的2/3/4。

    经过ServiceTracker优化后的Service Listener机制,还是存在一些缺点:
   
    1. 编码量还是不小,尤其对于依赖较多的场景

    2. Activator 还是太复杂了,尽管已经很努力的试图简化
        对于一些业务逻辑简单的service,如果依赖的service比较多,那么Activator的逻辑和代码实现远比service本身的逻辑和实现要复杂,这违背了我们使用框架简化开发的初衷。

    3. Activator对测试不利
        这个是Activator的复杂性造成的,由于Activator中存在大量的依赖处理逻辑,理所当然的会增加测试的复杂性。

    总结说,Service Listener 机制下,管理service依赖对于开发者来说完全是个重体力活: 很重要,经常要做,容易出现错误, 出错时不容易测试。而且,这些工作都不是service 业务逻辑的组成部分,不能带来直接收益。简言之,吃力不讨好,一不小心就搬石头砸自己的脚。

    更重要的,从分工的角度上将,开发人员应该将更多的精力投入与应用的逻辑,而不是OSGI的底层实现机制。因此,从2000之后,就陆续有人开始考虑对此改进。

2) Service binder

    Service binder OSGI针对这个问题的一个尝试,基本出发点非常明确:希望找到一个通用的方法来简化OSGI下的动态service依赖管理.

    最初开始这个工作的是两位大牛,Richard S. Hall和Humberto,大概在2002年的时候开发完成。

    看我们看Service binder是怎么做的,基本步骤为:

    1. 提供一个org.apache.felix.servicebinder.GenericActivator;
        现在bundle的Activator只要简单的继承GenericActivator就可以了,所有的代码实现在GenericActivator提供,减少代码的目标顺利达成。这个可以说足够简单到没有办法再简单了。
    2. 通过metadata.xml 来实现service的依赖注入

    3. 具体的service的实现类基本就是一个干净的POJO了
        当然还是需要实现bind-method/unbind-method 两个方法,好在这个是通过metadata.xml来做映射,不是另外提供接口定义,因此勉强避开了"侵入"的问题。

    Service binder 机制在减少Activator方面成效显著,但是引入的metadata.xml文件似乎又带来了新的问题,xml配置文件的可维护性个人感觉值得怀疑。用过EJB的同学都明白,EJB的部署文件有多令人烦恼。

    当然Service binder 的思路非常的正确:通过引入了自动化的service依赖关系管理,简化开发,允许开发人员可以集中精力在service的实现上,而不是疲于处理依赖关系管理。

    Service binder的实现似乎并没有被推广开,因为很快OSGI就在2004年的OSGI R4规范中引入了Declarative Services。因此Felix也就终止了对Service binder的后续支持。

       
3) Dependency Manager

    继Service binder之后,Felix又提供了名为Dependency Manager 的service依赖管理方式,对比Service binder,个人感觉这个Dependency Manager 只是针对Service binder的一个改进:将metadata.xml 文件取消,由新引入的DependencyManager来实现metadata.xml 文件的功能。原来在metadata.xml 文件中的配置转变为在Activator中通过代码调用DependencyManager来实现.

    Dependency Manager其实现的方式为:

    1. 提供org.apache.felix.dependencymanager.DependencyActivatorBase
        bundle的Activator需要继承DependencyActivatorBase,并实现DependencyActivatorBase要求的init()/destroy()方法
    2. 在init()中,可以通过DependencyManager 对象来注册服务,并注明依赖。

    3. 具体的Service类可以是POJO,DependencyManager 通过反射来注入依赖的service。

    Felix 官方给出了一个Dependency Manager的使用示例
http://felix.apache.org/site/dependency-manager-usage.html
    从示例上看,对service的依赖管理已经简化了许多。

    这里还有一个05年的介绍Dependency Manager的 presentation:
http://felix.apache.org/site/presentations.data/DependencyManagement.pdf

4) Declarative Services

    2004年发布的OSGi的4.0版本中,加入了Declarative Services,据说是从Service Binder进化而来。

    Declarative Services的实现方式和Service Binder的确非常相似:

    1. 同样是需要一个xml文件来配置
        在 bundle manifest中增加Service-Component 的header
        提供的功能和Service Binder很类似,配置方法也很接近。

    2. 同样的提供bind/unbind 方法的配置
        对于每个依赖的service,都可以在配置文件中通过指定bind/unbind 方法来处理依赖的状态变化。

    此外,Declarative Services 提供两个特殊的lifecircle方法:
        protected void activate(ComponentContext context)
            protected void deactivate(ComponentContext context)
    如果service实现类提供了这两个方法,则Declarative Services 会自动识别并调用这两个方法。注意这两个方法没有接口定义进行强约束,只是一个约定而已,估计是为了避免OSGI对service的侵入。

    Declarative Services 是OSGI规范的一部分,因此Declarative Services的支持自然是各个OSGI实现都提供的。

    从功能上将,Declarative Services 基本已经不错了,但是大牛们的脚步并未就此停住。

5) iPOJO

    2005年,Richard 开始考虑使用字节码生成技术来进行创建组合服务的改进,另外一个牛人Peter Kriens也同样的工作并实现了一个原型。
    2006年,Clement Escoffier 和 Richard 开始开发iPOJO,合并了Peter Kriens之前的工作内容,这就是iPOJO的由来。

    对于iPOJO的定义,Felix的iPOJO页面有如下说明:iPOJO是一个服务器组件运行时,目标在于简化OSGI应用开发。原生支持所有的OSGI活力。给予POJO的概念,应用逻辑开发简单。非功能性的属性在运行时被注入到组件中。

    同样看看Felix对iPOJO优点的说明:
   
    1. 组件被作为POJO开发,不需要其他任何东西
    2. 组件模块是可扩展的,因此可以自由的适应需要
    3. 标准组件模型管理service 供应和service 依赖,所以可以要求其他任何OSGI服务来创建组合服务,
    4. iPOJO管理组件实例的生命周期和环境动态
    5. iPOJO提供一个强力的组合系统来创建高度动态的应用
    6. iPOJO支持注解,xml或者基于Java的API来定义组件

    可以看到iPOJO的功能远比之前的几个解决方案要强大,除了支持Declarative Services已经实现的功能外,还提供了强大的注解支持,而且实现了组合系统,这些对于开发大型的复杂应用时非常有用的。

    Richard 在他的presentation谈到iPOJO 的设计思路:

    1. Make things simple / 让事情简单
    2. Follow POJO philosophy / 遵循POJO的哲学
    3. Employ byte code manipulation techniques / 使用字节码操纵技术
    4. Be as lazy as possible / 尽可能的偷懒

    目前的iPOJO还在继续发展中,最新的一个版本iPOJO 1.6.0在2010-04-25发布。

 

6) blueprint

 

blueprint 是OSGI为了解决上述问题的最新尝试,在去年刚发布的OSGI v4.2 规范中新加入了 Blueprint Container 的规范内容。

 

提到blueprint 就不能不提到spring Dynamic Modules,blueprint 可以认为是Spring Dynamic Modules版本的改进和标准化。SpringDM 1.x版本实现了Spring Dynamic Modules for OSGi,在Spring Dynamic Modules被标准化为Blueprint Container 规范后,新的SpringDM 2.x 则成为Blueprint的参考实现。

 

blueprint 的使用实行非常类似标准的spring IOC容器,比如同样的使用xml配置文件,只是从ioc 的applictionContext xml变成了Blueprint XML。而Blueprint XML的配置方式和spring 有惊人的相似。

举例,最简单的bean:

 

   <bean id="accountOne" class="org.apache.geronimo.osgi.Account">

       <argument value="1"/>

       <property name="description" value="#1 account"/>

   </bean>

 

基本就是照搬spring IOC的方式,对于熟悉spring的开发人员来说无疑是个好消息,起码学习曲线平缓了。

 

由于是OSGI的标准规范,blueprint 目前的支持还是不错的,除了上面说的SpringDM外,还有Geronimo Blueprint Container 和 Apache Felix Karaf 都提供了对blueprint的支持。

   
    总结,从上述的发展历程上看,OSGI中的service依赖关系管理方式,经历了从简单原始到逐渐成熟强大的过程,前后经历了大概10年的时间.
分享到:
评论
3 楼 xyz20003 2010-05-25  
多谢多谢,静待佳音。
2 楼 skydream 2010-05-25  
哦,对啊,怎么把这个给忘了,主要是blueprint 我不大了解,好吧,我现在就去磨枪,稍后就加上。
1 楼 xyz20003 2010-05-25  
没涉及blueprint,有些遗憾。

相关推荐

    浅析OSGI的bundle依赖

    在OSGI环境中,每个bundle都是一个独立的代码单元,具有自己的类路径,并且可以有自己的依赖关系。这篇博客“浅析OSGI的bundle依赖”可能探讨了如何管理和解决这些模块间的依赖问题。 首先,我们来看一下OSGI中的...

    OSGi_Service

    - **依赖管理**:OSGi框架负责管理Bundle间的依赖关系,确保正确版本的依赖被加载,并在需要时自动解决依赖。 **2. OSGi的优势** - **灵活性**:由于模块化的特性,开发者可以轻松地添加、删除或替换模块,而不...

    OSGi Service Platform 4.1

    7. **服务组件运行时(SCR)**:OSGi 4.1中的服务组件运行时(Service Component Runtime)提供了一种声明式的方式来定义和管理服务。开发者可以通过XML配置文件声明服务接口、实现和依赖关系,简化了服务的管理和...

    spring-osgi.jar及其依赖包

    Spring OSGi是Spring框架与OSGi(Open Service Gateway Initiative)规范集成的产物,它使得在OSGi环境中使用Spring变得更加方便。OSGi是一种模块化系统,用于Java应用程序,提供了动态服务发现、版本控制和依赖管理...

    OSGi (Open Service Gateway Initiative)入门

    框架负责管理bundle的生命周期,并确保它们之间的依赖关系得到正确处理。 - **Bundle**:bundle相当于Java应用程序中的模块,它是一个Java Archive(JAR)文件,包含了Java类、启动类(Activator Class)、清单文件...

    OSGi 模块管理 动态管理部

    - **依赖管理**:OSGi框架提供了一种机制来管理Bundles之间的依赖关系,确保每个Bundle都能访问其所需的资源。 - **版本控制**:支持精细的版本控制策略,确保即使在多版本共存的情况下也能正常工作。 - **服务层**...

    Osgi Service Platform

    OSGi(Open Service Gateway Initiative)服务平台是一种模块化框架,它允许在Java环境中构建、部署和管理复杂的应用程序和服务。OSGi最初旨在为家庭网关设备提供一种标准化的服务平台,但其模块化和动态性的特性使...

    Spring OSGI 快速入门中文教程

    OSGi(Open Service Gateway Initiative)是一种Java模块化系统,它允许开发者创建可热更新、可隔离且互相依赖管理的模块。Spring OSGi是Spring框架与OSGi服务的结合,使得在OSGi环境中使用Spring变得简单。本教程将...

    IntelliJ IDEA OSGI helloworld

    - **Framework**:是OSGi系统的运行时环境,管理Bundle的生命周期并处理它们之间的依赖关系。 - **Service**:是OSGi中提供功能接口的组件,可以被其他Bundle消费。 **2. 创建OSGi Bundle** 在IntelliJ IDEA中,...

    OSGI服务 DS EVENT

    开发者不再需要手动编写代码来管理服务的生命周期,如启动、停止、更新等,而是通过DS的元数据声明服务的依赖关系和行为。这样可以提高代码的可维护性和可测试性,同时降低了复杂性。 在DS中,EVENT主要涉及的是...

    Apress - Pro Spring Dynamic Modules for OSGi Service Platforms 2009

    通过阅读《Pro Spring Dynamic Modules for OSGi Service Platforms 2009》,开发者不仅可以掌握OSGi和Spring DM的核心原理,还能学习到如何在实际项目中有效地利用这些技术,以实现更灵活、可维护的企业级Java应用...

    OSGi入门篇:服务层

    通过服务化组件之间的交互,OSGi不仅让组件能够更加灵活地应对变化,还简化了依赖关系的管理,提高了开发和维护的效率。对于需要高度模块化、动态更新和维护的应用程序,OSGi服务层是一个非常有价值的工具。

    spring osgi相关资源

    Spring OSGi是Spring框架与OSGi(Open Service Gateway Initiative)规范相结合的一种技术,它允许在OSGi容器中运行和管理Spring应用。OSGi是一种模块化系统,为Java应用程序提供了动态部署、版本控制和依赖管理的...

    osgi 资料 总结 实践

    - **Framework**:OSGi框架是运行时环境,管理bundle的生命周期,处理它们的依赖关系,确保它们之间的安全隔离。 - **Service**:OSGi服务允许bundle之间共享功能,通过注册和查找服务来实现跨bundle通信。 - **...

    基于osgi构建小例子

    在Java世界中,OSGi提供了一种解决大型项目复杂性的有效方式,使得依赖管理变得更加灵活和可控。 本例子是为OSGi初学者设计的,它使用了Eclipse 3.5 IDE和JDK 1.6作为开发环境。Eclipse是一个流行的开源IDE,其本身...

    OSGi service

    它允许开发人员创建独立的模块(称为bundle),这些模块可以互相发现并交互,而无需关心它们的加载顺序或依赖关系。OSGi服务层是OSGi框架的核心特性,提供了发布、绑定和查找服务的能力,使得服务提供者和服务请求者...

    解决osgi spring 事务配置问题

    在OSGi(Open Service Gateway Initiative)环境中配置Spring事务可能会遇到一些挑战,因为OSGi的模块化特性使得依赖管理和类加载机制与传统的Java应用不同。这篇博客文章“解决osgi spring 事务配置问题”可能深入...

    OSGI

    4. **依赖管理**:OSGI框架自动管理bundle之间的依赖关系,确保在运行时只有当所有依赖满足时,bundle才会被激活。 5. **版本管理**:OSGI支持多版本共存,每个bundle都可以指定其依赖的具体版本,增强了系统的兼容...

    osgi介绍osgi介绍

    3. **依赖管理**:OSGi框架自动处理bundle之间的依赖关系,确保依赖的bundle在需要时可用。 4. **版本控制**:支持多版本共存,同一个服务可以有多个版本同时存在,bundle可以选择使用哪个版本。 5. **安全**:OSGi...

Global site tag (gtag.js) - Google Analytics