Как создать несколько экземпляров службы osgi без использования аннотаций DS - PullRequest
0 голосов
/ 05 октября 2018

Я создал сервис 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?

Ответы [ 2 ]

0 голосов
/ 09 октября 2018

Для меня это похоже на случай, когда вы задали вопрос, основанный на том, что вы думаете, а не на описании того, чего вы пытаетесь достичь.Если мы сделаем несколько шагов назад, то найдется более элегантное решение.

В общем, внедрение объектов в службы с сохранением состояния - плохой шаблон в OSGi.Это заставляет вас быть очень осторожным с жизненным циклом и рискует утечки памяти.Из примера кода видно, что вы действительно хотите, чтобы ваш потребитель получил уведомление, когда происходит событие в теме администратора событий.Самый простой способ сделать это - удалить XyzHandler из уравнения и сделать Consumer обработчиком событий, например так:

@Component(property= { EventConstants.EVENT_TOPIC + "=" + DEPLOY,
                       EventConstants.EVENT_TOPIC + "=" + UNDEPLOY})
public class Consumer implements EventHandler {

  private DataSourceCache cache;

  @Override
  public void handleEvent(final Event event) {
    notify();          
  }

  public void notify() {
    updateCache(cache);
    System.out.println("cache updated");
  }

  public void updateCache(DataSourceCache cache) {
       cache = null;
  }
}

Если вы действительно не хотите, чтобы ваш Consumer был EventHandler тогда было бы проще зарегистрировать Потребителя в качестве службы и использовать шаблон доски для его подбора одним XyzHandler:

@Component(service=Consumer.class)
public class Consumer {

  private DataSourceCache cache;

  public void notify() {
    updateCache(cache);
    System.out.println("cache updated");
  }

  public void updateCache(DataSourceCache cache) {
       cache = null;
  }
}

@Component(property= { EventConstants.EVENT_TOPIC + "=" + DEPLOY,
                       EventConstants.EVENT_TOPIC + "=" + UNDEPLOY})
public class XyzHandler implements EventHandler {

  // Use a thread safe list for dynamic references!
  private List<Consumer> consumers = new CopyOnWriteArrayList<>();

  @Reference(cardinality=MULTIPLE, policy=DYNAMIC)
  void addConsumer(Consumer consumer) {
    consumers.add(consumer);
  }

  void removeConsumer(Consumer consumer) {
    consumers.remove(consumer);
  }

  @Override
  public void handleEvent(final Event event) {
    consumers.forEach(this::notify);          
  }

  private void notify(Consumer consumer) {
    try {
      consumer.notify();
    } catch (Exception e) {
      // TODO log this?
    }
  }
}

Использование шаблона доски таким образом избавит вас от необходимостиотследить, какой XyzHandler необходимо создать / уничтожить при запуске или остановке пакета, и он сделает ваш код намного чище.

0 голосов
/ 06 октября 2018

Похоже, что ваш сервис должен быть прототипом сервиса .Это было введено в Core R6.DS 1.3, из Compendium R6, включает поддержку компонентов, которые будут службами прототипа .

Но DS 1.2 предшествует Core R6 и, таким образом, не знает и не поддерживает службы прототипа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...