假设我在套件A中有一个EventGenerator服务,在套件B和C中有处理器(侦听器)。
A对B和C一无所知,其中处理器在初始化时为EventGenerator事件订阅。
在其他捆绑包D,E等中可以创建更多的侦听器。

在春季应用程序中,我将在构造Processor时进行订阅,将EventGenerator作为构造函数参数传递。 我将B和C逻辑上依赖于A。在@PostConstruct上,我将拥有一个可以处理事件的操作系统。

如何将A,B和C初始化为OSGi应用程序? 当EventGenerator开始工作并且处理器错过事件时,我遇到了问题,因为它们尚未初始化并订阅它们。

===============>>#1 票数:1

您试图实现的目标在OSGi中是不可能的。 原因是,在部署EventGenerator捆绑软件时,您不知道将发生什么捆绑软件部署事件以及以什么顺序进行。

在Spring中,所有事物都是同时部署的,因此可以对其进行分析,哪些bean实现了Processor接口。

有两种解决方法,您必须选择最适合您的一种。

LogService

您可以在OSGi规范中找到“ 日志服务”一章。 LogListener实现可以注册为OSGi服务。 LogService实现获取每个LogListener服务并为其发送每个LogEvent

这里的问题是,已经发生LogEvent之后可能会注册LogListener

此处的解决方案是告诉LogService应该存储多少条记录,如果LogListener已注册,请首先发送最后的X个事件。 据我所知Equinox LogService的默认设置是它记住最近的100个LogEvents

类似BundleTracker的事件

BundleTracker事件的特殊性是活动事件的数量是有限的。 事件不再重要后,将其删除。 在实践中:

  • 在容器中放入捆绑包之前, 捆绑包的最后一个事件由每个新打开的BundleTracker进行存储和处理
  • 捆绑包标记为删除后,其最后一个事件将被删除

如果发生此类事件,则可以实施相同的方法。 实现起来并不容易。 我实现了一个库,使工作变得更轻松。 您需要实现一些接口并通过泛型定义类型,您将具有必要的事件管理功能: https : //github.com/everit-org/eventdispatcher

等待所有处理器,然后再启动EventGenerator

如果没有以前的解决方案对您有用 ,您必须以某种方式告诉EventGenerator组件,直到所有处理器都拿起后才注册其OSGi服务。

我认为,最好的方法是通过ConfigAdmin使其可配置。 这样,您就可以通过命令行控制台WebConsole重新配置EventGenerator组件,而无需重新启动系统。

我实现了组件模型以具有此功能。 您的组件如下所示:

import org.everit.osgi.ecm.annotation.Component;
import org.everit.osgi.ecm.annotation.Service;
import org.everit.osgi.ecm.annotation.ServiceRef;
import org.everit.osgi.ecm.extender.ECMExtenderConstants

import aQute.bnd.annotation.headers.ProvideCapability;

@Component
@Service
@ProvideCapability(ns = ECMExtenderConstants.CAPABILITY_NS_COMPONENT,
    value = ECMExtenderConstants.CAPABILITY_ATTR_CLASS + "=${@class}")
public class EventGenerator {

  private Processor[] processors;

  @ServiceRef
  public void setProcessors(Processor[] processors) {
    this.processors = processors;
  }
}

您可以在组件的processors.target属性中通过一系列OSGi过滤器指定必要的Processor OSGi服务。 在所有处理器可用之后,该组件将启动并将其注册为服务。

为了使上述工作同样有效,您必须将以下依赖项(及其传递性依赖项,小于200k)放到OSGi容器中:

<dependency>
  <groupId>org.everit.osgi</groupId>
  <artifactId>org.everit.osgi.ecm.extender.ri</artifactId>
  <version>1.0.0</version>
</dependency>

还有一个WebConsole插件,可以显示组件的状态(为什么不满意或失败):

<dependency>
  <groupId>org.everit.osgi</groupId>
  <artifactId>org.everit.osgi.ecm.component.webconsole</artifactId>
  <version>1.0.0</version>
</dependency>

  ask by Mykhaylo Adamovych translate from so

未解决问题?本站智能推荐: