Java OSGI:包启动后声明性服务可用吗
问题很简单,但我找不到答案-我可以声明bundle A中的所有声明性服务在bundle A启动后都可用吗?比如说,Java OSGI:包启动后声明性服务可用吗,java,osgi,apache-felix,declarative-services,Java,Osgi,Apache Felix,Declarative Services,问题很简单,但我找不到答案-我可以声明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? 另外,我使用ApacheFelix,但我认为它必须在规范中定义,而不是在实现中定义 编辑: 我假设D
bundle=context.installBundle("file:bundleA-1.0.0.jar");
bundle.start();
//In this point are declarative services of bundle A 100% available?
另外,我使用ApacheFelix,但我认为它必须在规范中定义,而不是在实现中定义
编辑:我假设DS运行时正在运行,配置存在,并且所有必需的引用都存在。您不能假设所有DS组件在bundle启动后都可以作为服务使用。首先,DS运行时必须也在运行。然后默认情况下,DS组件被延迟激活。这意味着它们只有在其他包需要此类服务时才处于活动状态,并且最后但并非最不重要的组件只有在其所有必需引用都存在时才被激活。
好。。。在我忘记之前,您还可以定义组件只有在配置存在时才被激活。您不能假设所有DS组件在捆绑启动后都可以作为服务使用。首先,DS运行时必须也在运行。然后默认情况下,DS组件被延迟激活。这意味着它们只有在其他包需要此类服务时才处于活动状态,并且最后但并非最不重要的组件只有在其所有必需引用都存在时才被激活。
好。。。在我忘记之前,您还可以定义组件只有在配置存在时才被激活。您的问题的答案非常简单:不。OSGi中的可用性无论是基于时间还是顺序都无法保证。服务事件中指定了唯一的保证 在代码中进行计时/排序假设是造成复杂性的最大原因之一,因为它们总是以最模糊的方式被违反 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);
}
}
你的问题的答案很简单:不。OSGi中的可用性无论是基于时间还是顺序都无法保证。服务事件中指定了唯一的保证 在代码中进行计时/排序假设是造成复杂性的最大原因之一,因为它们总是以最模糊的方式被违反 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);
}
}
在这种情况下,只有延迟加载仍然是一个原因。您是否使用immediate=true?我认为可用服务和创建实例的服务之间存在差异。当我说可用时,我的意思是如果这个服务是必要的,那么OSGI框架将创建它的实例。这只是一个理论问题,还是您有一个似乎没有启动的具体服务。在这种情况下,只有延迟加载仍然是一个原因。您是否使用immediate=true?我认为可用服务和创建实例的服务之间存在差异。当我说可用时,我的意思是如果这个服务是必要的,那么OSGI框架将创建它的实例。这只是一个理论问题,还是你有一个似乎还没有开始的具体服务。这些都是你真的无法做出的假设。这些都是你真的无法做出的假设。让我们假设我只有一个声明性服务-服务a。我需要在普通代码,不在另一个osgi服务中。所以我理解你的意思是对的——在这种情况下,唯一的方法就是使用ServiceTracker?ServiceTracker可以工作,但有一个更简单的解决方案。问题是控制(我认为这是编写代码中最有趣、讨论最少的方面之一)。我可能会做的是在非OSGi端注册BundleActivator服务,然后在OSGi端创建具有适当依赖关系的即时DS组件。该组件在激活/停用时调用框架端服务。通过这种方式,您可以在DS端拥有控制权,而非OSGi端紧随其后。。但是你们能用代码举例说明你们的意思吗?非常感谢,现在我需要理解你们的代码。抱歉我的问题…在你的代码之后,我想我根本不知道osgi。什么是框架?这是什么课?我可能误解了你的问题。我理解您将代码作为捆绑包和在框架之外运行的代码来运行。如果您的所有代码都作为一个包运行,那么为什么不直接使用DS呢?假设我只有一个声明性服务——服务a。我需要在普通代码中使用此服务,而不是在另一个osgi服务中使用。所以我理解你是对的,唯一的方法就是在这种情况下使用服务跟踪器