首页 > 解决方案 > 如果我的服务启动时间早于引用的一半,如何更新 OSGI @Reference 列表

问题描述

这是对“OSGI 捆绑包没有激活顺序”这一​​主题进行挖掘的又一次尝试。

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

@Reference
private volatile List<DataProvider> dataProvider;

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

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

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

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

标签: javareferenceosgibundledeclarative-services

解决方案


您可以在配置中指定最小基数。在您的情况下,这是使用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注释方法指定过滤器。


推荐阅读