OSGI:声明性服务在捆绑包启动后变得可用

OSGI: do declarative services become available after bundle start

问题很简单,但我找不到答案 - 我可以声明 bundle A 中的所有声明性服务在 bundle A 启动后可用吗?例如,

bundle=context.installBundle("file:bundleA-1.0.0.jar");
bundle.start();
//In this point are declarative services of bundle A 100% available?

P.S。我用的是apache felix,但我认为它必须在Specs中定义而不是在实现中。

编辑:
我假设 DS 运行时是 运行,存在配置并且存在所有强制引用。

您不能假定所有 DS 组件在捆绑包启动后都可作为服务使用。首先是DS运行时也必须是运行。然后默认情况下 DS 组件被延迟激活。这意味着它们仅在某些其他捆绑包需要此类服务时才处于活动状态,并且最后但并非最不重要的组件仅在其所有强制引用都存在时才被激活。 好吧......在我忘记它之前,你还可以定义一个组件只有在存在配置时才会被激活。

你问题的答案很简单:不。无论是基于时间还是顺序,都无法保证 OSGi 中的可用性。唯一的保证在服务事件中指定。

在代码中做出 timing/ordering 假设是造成复杂性的最大原因之一,因为它们总是以最隐蔽的方式被违反。

DS 使得编写能够在服务依赖关系出现和消失时正确做出反应的代码变得微不足道。确保您获得与服务相关的保证非常复杂,如果您开始假设某些东西 应该 在您调用方法后可用,那么您会破坏所有的价值。

在您的示例中,仅依赖您需要的服务。如果该服务可用,那么您确定所有初始化都已完成。

如果您坚持服务依赖性,在 OSGi 中的生活会相当轻松且非常健壮。

问题后更新示例

一个非 OSGi 端:

 systemBundleContext = ... create framework
 systemBundleContext.registerService( 
    BundleActivator.class, 
    new BundleActivator() {
        public void start(BundleContext c) {
           // start non-OSGi code
        }
        public void stop(BundleContext c) {
           // stop non-OSGi code
        }
     },
     null );

DS 组件:

 @Component
 public class Initiator {
    @Reference
    BundleActivator ba;

    @Referenc
    MyService myService;

    @Activate void activate(BundleContext context) throws Exception {
      ba.start(context);
    }

    @Deactivate void deactivate(BundleContext context) throws Exception {
      ba.stop(context);
    }
 }