【问题标题】:Intra- and inter-bundle mutual dependencies in OSGi component modelsOSGi 组件模型中的捆绑内和捆绑间相互依赖关系
【发布时间】:2012-05-21 01:06:51
【问题描述】:

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

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) 当它们在不同的包中时?

【问题讨论】:

    标签: osgi declarative-services ipojo blueprint-osgi


    【解决方案1】:

    声明式服务规范,版本 1.1:

    112.3.5 循环引用

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

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

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

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

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

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

    所有部分初始化的组件实例必须在 蓝图容器进入运行时阶段,在调用 getComponentInstance 方法返回一个组件实例。用户代码 通过递归调用 必须检测到 getComponentInstance 方法并导致失败,这些 循环不能被打破。

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

    对于 iPOJO

    支持您的具体情况。我不能谈论其他情况 虽然不知道进一步的描述。

    (在邮件列表中收到答复)。

    【讨论】:

      【解决方案2】:

      严格来说,你说的是不可能的,因为循环依赖。

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

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

      您可以在所有三个框架中执行此操作。 iPojo 有optional references,DS 有一个服务需求的基数设置(使用 0..1 作为可选引用而不是 1..1)。蓝图我不是很了解,但我确信可以做到。

      问候,弗兰克

      【讨论】:

      • "Service1 只能在 Service2 处于活动状态时才能运行,反之亦然,因此框架启动您的服务没有顺序。"该框架可以创建两个实例而不发布它们(因此它们不能被客户端代码调用并且缺少引用不是问题)然后发布。或者它可以发布一个实例而不引用另一个实例,并确保对它的所有调用都阻塞,直到第二个被创建。例如。这适用于@Autowired Spring beans。
      • 查看 DS 规范,实际上在这种情况下没有提供其他服务(参见 112.3.5)。
      • iPOJO 也有时间依赖来处理这种情况。
      猜你喜欢
      • 2022-01-23
      • 2015-10-04
      • 2017-09-10
      • 2015-03-12
      • 1970-01-01
      • 2016-07-13
      • 2013-11-02
      • 1970-01-01
      • 2014-11-20
      相关资源
      最近更新 更多