【问题标题】:Initialization of OSGi prototype componentsOSGi 原型组件的初始化
【发布时间】:2019-05-13 17:18:36
【问题描述】:

在 OSGi 声明式服务中,我可以像这样创建声明 ComponentServiceObjects 的原型实例:

@Reference(unbind = "-",
           scope=ReferenceScope.PROTOTYPE_REQUIRED)
private ComponentServiceObjects<MyService> serviceProvider;

然后实例化服务

service = serviceProvider.getService();

然后我可以通过使用 setter 设置一些其他属性(配置值或非 OSGi 协作者)来完成实例的配置。这有一个问题,即在初始化完成之前执行激活。

有没有办法在激活服务之前注入这个属性?

我在 Liferay Portal 7 的上下文中使用 DS

编辑

作为澄清,我有一个例子:假设我有一个组件 DirectoryListener。我想初始化这个组件的几个实例,每个实例都有一个不同的目录。我想在激活过程中根据这个目录做一些初始化。

【问题讨论】:

  • 你能澄清一下吗?您想在组件初始化完成之前调用服务上的一些方法吗?那是不可能的...... DS 提供的保证是组件将在任何服务使用者调用任何方法之前完全初始化。
  • 顺便说一句,@Reference 上的 unbind="-" 属性什么都不做,应该删除。
  • 感谢您对取消绑定的评论!我在我的代码中使用它是因为我在很多其他地方都看到过它,但我觉得它没用。
  • 作为澄清,我有一个例子:假设我有一个组件DirectoryListener。我想初始化这个组件的几个实例,每个实例都有一个不同的目录。我想在激活过程中根据这个目录做一些初始化。如果不可能,我将不得不使用另一种在激活后运行的方法。还是有更好的方法?
  • 不,这是不可能的,组件的客户端无法决定该组件的配置。听起来你想注册一个DirectoryListenerFactory

标签: java osgi declarative-services


【解决方案1】:

服务的消费者对实现组件一无所知......或者实际上服务是否由组件实现,而不是更底层的东西。因此它不能决定组件的配置。

听起来您的用例要求将目录作为服务 API 的一部分,因此您的服务接口应该是 DirectoryListenerFactory。该组件可以注册为一个简单的单例服务,并且目录将通过方法传递,例如createListener(File dir).

在这种情况下,您需要注意生命周期。如果客户端调用createListener,它应该小心释放不再需要的侦听器。例如DirectoryListener 可以扩展java.lang.AutoCloseable

任何服务依赖都可以通过@Reference 注入到实现工厂的组件类中。我希望它们通过构造函数传递给DirectoryListener 实例。

【讨论】:

    【解决方案2】:

    尼尔·巴特利特:

    不,这是不可能的,组件的客户端无法决定该组件的配置。听起来您想注册一个DirectoryListenerFactory

    【讨论】:

      猜你喜欢
      • 2018-08-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-28
      • 2022-11-30
      相关资源
      最近更新 更多