Osgi 具有声明性服务的多个引用和依赖项

Osgi 具有声明性服务的多个引用和依赖项,osgi,apache-karaf,declarative-services,Osgi,Apache Karaf,Declarative Services,我在通过Karaf使用OSGi声明服务加载组件时遇到问题 我有这样的情况: @Component public class A implements IA { doSomething() {...} } @Component public class B implements IB {} @Component public class C implements IC { @Reference IA a @Reference (cardinality = Refer

我在通过Karaf使用OSGi声明服务加载组件时遇到问题

我有这样的情况:

@Component
public class A implements IA
{
  doSomething() {...}
}


@Component
public class B implements IB
{}

@Component
public class C implements IC
{
  @Reference 
  IA a

  @Reference 
  (cardinality = ReferenceCardinality.MULTIPLE,
   policyOption = ReferencePolicyOption.GREEDY,
   unbind = "doUnRegister" )
  void doRegister(IB b)
  {
    a.doSomething()
  }

  void doUnregister(IB b)
  {
    ...
  }
}
A、 B和C是三个不同的束

当启动Karaf时,注册一个B并调用doRegister。但是:服务A未准备好,服务A为空

我尝试了以下方法:

将A的起始级别设置为低于B的某个级别。。。不起作用 在工作列表中获取B的注册,并在激活C后实际使用a。没有工作,代码混乱。 正在搜索通过doRegister上的注释编写此需求的方法-不可能。 我试图使用一个服务定位器,并通过C上的激活方法获取上下文-没有工作,它使Karaf崩溃。 我肯定错过了什么,有没有人经历过类似的问题并找到了解决方案

更新:
参考A更改为IA A。添加了关于参考B的遗忘信息。

根据您提供的示例代码,在出现A和B之前,C不会被激活,因为对A和B的引用是静态的、强制性的引用。因此,开始订购是不相关的

此外,引用是按照在组件描述XML中写入的顺序设置的。当Bnd将注释处理为组件描述XML时,它会按引用名称的顺序写出引用。可以显式设置引用名称,并默认为带注释成员的名称。因此,在您的示例代码中,a位于doRegister之前,因此字段a将在调用doRegister之前设置


我的猜测是,在您将实际代码简化为本例的过程中,您丢失了一些理解问题的重要信息。这将包括引用的静态/动态和强制性/可选性质以及引用名称。

示例类是否完整?B是否实现和接口,A是否实现?谢谢您的指点。但是是的,A、B和C都有接口支持,问题仍然存在。你能给github或类似的网站发布一个完整的小例子吗?这个例子是一个更大的代码库的一部分,所以我在提取这个例子时遇到了一些问题。你确定这是正确的吗?当您注入未注册为服务的A和B时,服务将注册为IA和IB。更新:我已更新示例程序,其中包含有关引用注释和接口正确使用的更多详细信息。ReferenceCardinality.MULTIPLE为0..n。所以,如果组件C在组件B之前启动,那么C的引用be将很高兴地满足于零Bs。另外,如果您查看为组件C生成的组件描述XML,您应该会看到字段A的引用元素位于bind方法doRegister的引用元素之前。这意味着在绑定B并调用doRegister之前,A将被绑定,字段A将被设置。