如何在不使用 DS 注释的情况下创建 osgi 服务的多个实例

我创建了一个 Osgi 服务。每次收到服务请求时,我都想为我的服务创建一个新实例。代码看起来像这样 -


    @Component(immediate=true)

    @Service(serviceFactory = true)

    @Property(name = EventConstants.EVENT_TOPIC, value = {DEPLOY, UNDEPLOY })

    public class XyzHandler implements EventHandler {

         private Consumer consumer;

         public static setConsumer(Consumer consumer) {

          this.consumer = consumer;

          }

     @Override

        public void handleEvent(final Event event) {

                consumer.notify();          

     }

 }


public class Consumer {


private DataSourceCache cache;

public void notify() {

  updateCache(cache);

  System.out.println("cache updated");

 }

public void updateCache(DataSourceCache cache) {

   cache = null;

  }

}

在我的 Consumer 类中,我想访问 XyzHandler 的服务实例并设置属性消费者。此外,我希望每次为每个请求创建一个新的 XyzHandler 服务实例。我发现很少有文章提到使用 osgi 声明式服务注释可以实现这一点。 OSGi如何运行一个服务的多个实例


但我想在不使用 DS 1.3 的情况下实现这一点。


如何在不使用注释的情况下执行此操作,或者如何使用 DS 1.2 完成此操作?


互换的青春
浏览 186回答 2
2回答

隔江千里

对我来说,这看起来像是根据您认为答案的内容提出问题,而不是描述您想要实现的目标。如果我们退后几步,那么存在更优雅的解决方案。通常,将对象注入有状态服务是 OSGi 中的一种糟糕模式。它迫使您对生命周期非常小心,并冒着内存泄漏的风险。从示例代码看来,您真正想要的是让您的消费者在事件管理主题上发生事件时得到通知。最简单的方法是从等式中删除 XyzHandler 并使消费者成为这样的事件处理程序:@Component(property= { EventConstants.EVENT_TOPIC + "=" + DEPLOY,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;EventConstants.EVENT_TOPIC + "=" + UNDEPLOY})public class Consumer implements EventHandler {&nbsp; private DataSourceCache cache;&nbsp; @Override&nbsp; public void handleEvent(final Event event) {&nbsp; &nbsp; notify();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; }&nbsp; public void notify() {&nbsp; &nbsp; updateCache(cache);&nbsp; &nbsp; System.out.println("cache updated");&nbsp; }&nbsp; public void updateCache(DataSourceCache cache) {&nbsp; &nbsp; &nbsp; &nbsp;cache = null;&nbsp; }}如果你真的不想让你的ConsumeranEventHandler那么将消费者注册为服务并使用白板模式让它被一个人接收仍然会更容易XyzHandler:@Component(service=Consumer.class)public class Consumer {&nbsp; private DataSourceCache cache;&nbsp; public void notify() {&nbsp; &nbsp; updateCache(cache);&nbsp; &nbsp; System.out.println("cache updated");&nbsp; }&nbsp; public void updateCache(DataSourceCache cache) {&nbsp; &nbsp; &nbsp; &nbsp;cache = null;&nbsp; }}@Component(property= { EventConstants.EVENT_TOPIC + "=" + DEPLOY,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;EventConstants.EVENT_TOPIC + "=" + UNDEPLOY})public class XyzHandler implements EventHandler {&nbsp; // Use a thread safe list for dynamic references!&nbsp; private List<Consumer> consumers = new CopyOnWriteArrayList<>();&nbsp; @Reference(cardinality=MULTIPLE, policy=DYNAMIC)&nbsp; void addConsumer(Consumer consumer) {&nbsp; &nbsp; consumers.add(consumer);&nbsp; }&nbsp; void removeConsumer(Consumer consumer) {&nbsp; &nbsp; consumers.remove(consumer);&nbsp; }&nbsp; @Override&nbsp; public void handleEvent(final Event event) {&nbsp; &nbsp; consumers.forEach(this::notify);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; }&nbsp; private void notify(Consumer consumer) {&nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; consumer.notify();&nbsp; &nbsp; } catch (Exception e) {&nbsp; &nbsp; &nbsp; // TODO log this?&nbsp; &nbsp; }&nbsp; }}以这种方式使用白板模式可避免您XyzHandler在启动或停止包时跟踪需要创建/销毁的内容,并使您的代码更清晰。

一只斗牛犬

听起来您的服务需要是原型范围服务。这是在 Core R6 中引入的。来自 Compendium R6 的 DS 1.3 包括对组件作为原型范围服务的支持。但是 DS 1.2 早于 Core R6,因此不知道或不支持原型范围服务。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java