在我目前的应用程序中,我在几个地方遇到过这种模式:我在一个捆绑包中有两个服务接口,它们执行不同但相关的工作。
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)当Service1Impl
和Service2Impl
在同一个捆绑中时; 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)。蓝图我不太清楚,但我确信它可以做到。
问候,弗兰克