如果我的服务启动早于引用服务的一半,如何更新 OSGI @Reference List

how to update OSGI @Reference List if my service starts earlier than half of referenced ones

这是对“没有 OSGI 包激活顺序”主题的又一次尝试。

我有 4 个服务(捆绑包)实现了相同的接口 DataProvider,这意味着它们按字面意思实现了它,并且在它们的 @Component 注释中也将其作为 service = { DataProvider.class }。此接口提供来自这些服务的诊断数据之类的东西。我想从所有 4 个服务收集这些数据并将其打印在 GUI 上,这也是我的大框架中的一个 OSGI 包。为此,我在我的 GUI 包中创建了这样一个参考:

@Reference
private volatile List<DataProvider> dataProvider;

然后我想遍历该列表并将我需要的所有内容附加到 GUI 的文本框。

问题是,当 GUI 包启动时,四个服务中只有两个被激活,所以我的列表将只包含两个服务对象而不是所有四个服务对象,并且只打印它们。最后两个服务是在我的 GUI Bundle 已经激活之后加载的,因为它们也在等待它们自己的引用完全满足(其中一些网络操作已经完成,所以需要一些时间,大约 10 秒)。当然,我希望我的 GUI 显示所有 4 项服务的诊断数据。我能为此做什么?

我试图将 policyOption = ReferencePolicyOption.GREEDY 添加到 @Reference 注释中,我预计它会在每次此 List<DataProvider> dataProvider 收到新成员时强制重新激活 GUI 包,但没有,它没有不会发生。

P.S。是的,肯定有一个简单的解决方案:只需将 Thread.sleep() 添加到 GUI Bundle 中,并添加一些适当的值,这样到唤醒时,上面讨论的列表将已满。但这真的很糟糕,我不希望用户在出现 GUI 之前等待 10 秒,更不用说出现问题时的情况。

您可以在配置中指定最小基数。在您的情况下,这是在组件配置中使用 dataProvider.minimum.cardinality 属性 指定的。 (参见第 112.6.2.2 节最小基数 属性。)

package com.example;
@Component
public class Diagnostics {
    @Reference
    List<DataProvider> dataProvider;
}

那么需要为PID添加一条配置记录com.example.Diagnostics:

dataProvider.minimum.cardinality = 4

这种使用配置的模型非常适合 Configurator Specification。使用此规范,您可以在捆绑包中指定应用程序的配置。

或者,您可以创建 4 个引用并通过 属性 区分服务,使用 target 注释方法指定过滤器。