OSGi组件模型中的束内和束间相互依赖性

时间:2012-05-12 23:36:14

标签: osgi declarative-services ipojo blueprint-osgi

在我目前的应用程序中,我在几个地方遇到过这种模式:我在一个捆绑包中有两个服务接口,它们执行不同但相关的工作。

interface Service1 { ... }

interface Service2 { ... }

并希望单例组件实现两者,但是每个组件都需要引用另一个组件:

public class Service1Impl implements Service1 { 

    private Service2 service2;
    ...

}

public class Service2Impl implements Service2 { 

    private Service1 service1;
    ...

}

三个OSGi组件模型中的哪一个(DS,Blueprint和iPOJO)允许这样做:1)当Service1ImplService2Impl在同一个捆绑中时; 2)当他们在不同的捆绑中?

2 个答案:

答案 0 :(得分:6)

声明服务规范,版本1.1:

  

112.3.5循环参考

     

一组组件描述可以创建循环依赖关系。例如,如果   组件A引用组件B和提供的服务   组件B引用组件A提供的服务,然后是a   没有一个组件的组件配置就不能满足   访问另一个的部分激活的组件实例   零件。 SCR必须确保组件实例永远不会   可以访问另一个组件实例或作为服务,直到它具有   已完全激活,即它已从其activate方法返回   如果它有一个。

     

SCR时必须检测循环引用   尝试满足组件配置和SCR必须失败   满足循环中涉及的引用并记录错误消息   使用日志服务(如果存在)。但是,如果其中一个参考文献   循环有可选的基数SCR必须打破循环。该   具有可选基数的引用可以被满足和约束   零目标服务。因此,循环被打破,另一个循环   引用可能会得到满足。

蓝图规范明确允许这一点,前提是至少有一个依赖循环成员将其他成员作为属性而不是参数(121.2.6循环依赖):

  

当请求循环的成员提供组件实例时,   Blueprint Container必须通过在循环成员中找到一个破坏成员来打破循环。破坏成员必须使用属性注入   对于导致循环的依赖性。 Blueprint Container可以选择   如果没有这样的构件,用于破坏构件的循环的任何合适的构件   可以找到,然后初始化失败或getComponentInstance   方法必须抛出组件定义异常。

     

破坏成员必须返回部分初始化的组件实例   当它被要求提供一个对象时。部分初始化的对象已完成   所有可能的初始化但尚未使用initMethod调用(如果   指定的)也没有注入导致循环的任何属性。   部分初始化的组件实例的最终化必须是   延迟直到破坏成员被注入循环的所有引用成员。完成意味着注入任何剩余的未设置属性并调用initMethod(如果已指定)。

     

部分初始化组件实例的结果是它们   可以在设置所有属性之前使用,应用程序必须知道   这个。

     

所有部分初始化的组件实例必须在之前完成   Blueprint Container进入运行阶段,然后调用   getComponentInstance方法返回一个组件实例。用户代码   通过递归调用来导致动态循环   必须检测getComponentInstance方法并导致失败,这些   周期不能被打破。

     

应记录所有检测到的周期。

对于iPOJO

  

支持您的具体情况。我无法谈论其他情况   但不知道进一步的描述。

(在邮件列表上收到回复)。

答案 1 :(得分:3)

严格来说,由于循环依赖,你所说的是不可能的。

Service1只能在Service2处于活动状态时运行,反之亦然,因此框架无法启动您的服务。

据我所知,如果您将其中一个服务引用作为可选项,可以使其正常工作,因此它可以在它注入服务之前提供服务,因此其他serviceimpl可以提供它的服务回来。

您可以在所有三个框架中执行此操作。 iPojo有optional references,DS具有基本设置以满足服务要求(使用0..1作为可选参考而不是1..1)。蓝图我不太清楚,但我确信它可以做到。

问候,弗兰克