我正在开发一个由多个捆绑包组成的 OSGi 应用程序。所有这些都依赖于 EventAdmin 之一。但是,一个特定的插件必须在捆绑启动后立即启动计划任务(即在激活器的启动方法中)。问题是事件管理服务尚未注册,我应该等待部署。我不想通过配置属性文件执行此操作,因此,如果没有 Felix 的属性文件,是否有任何操作可以执行此操作?
非常感谢提前
OSGi 中没有开始排序...克服它...虽然有影响初始启动顺序的机制,但问题是任何捆绑软件都可以随时停止。因此,唯一的解决方案是实际处理您对 Event Admin 的依赖。
使用声明式服务 (DS),这实际上是很少的工作。另外,请忘记捆绑激活器,它们是捆绑单例,因此是个坏主意。因此,在 DS 中,您将执行以下操作(使用注释):
@Component(immediate=true)
public class MyTask extends Thread {
EventAdmin ea;
public void run() {
while ( !isInterrupted()) {
// do something
ea.postEvent(...);
}
}
@Activate void activate() { this.start();}
@Deactivate void deactivate() { this.interrupt(); }
@Reference void setEventAdmin(EventAdmin ea) { this.ea = ea;}
}
在极少数情况下,您不应该使用 DS 并被 Bundle-Activators 卡住,但它们很少见,应该变得更罕见。如果您遇到这样一个非常糟糕的情况,那么您还可以在 Bundle Activator 启动方法中创建一个服务跟踪器并跟踪 Event Admin 服务。一旦你得到一个,你创建一个线程来运行你的代码。当服务消失时,您会中断线程。然而,这是一个更复杂的解决方案。
还有其他服务依赖管理器,但我强烈推荐带有注释的声明式服务。
我为此使用了 iPOJO。它被设计用于 felix & karaf。该库了解组件的生命周期和依赖关系,当组件依赖关系可用或一个或多个依赖关系消失时,您将通过 @Validate 和 @Invalidate 方法收到通知。
当服务(接口)的实现出现或消失时,它还支持@Bind 和@Unbind。这使订阅变得更加简单。
您有一个服务的侦听器,并且此组件 @Provides 提供一个要调用的接口。然后,当这样的组件出现时,将在其 @Bind 方法上调用中央事件寄存器,并在它因任何原因消失时调用 @Unbind。
我怀疑 iPOJO 应该做所有你需要的依赖管理和绑定。