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



这是对主题"没有OSGI束激活的顺序";。

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

@Reference
private volatile List<DataProvider> dataProvider;

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

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

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

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

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

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

因此,您需要添加PIDcom.example.Diagnostics:的配置记录

dataProvider.minimum.cardinality = 4

这种使用配置的模式与配置程序规范配合得很好。使用此规范,您可以在捆绑包中指定应用程序的配置。

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

最新更新