Для меня это похоже на случай, когда вы задали вопрос, основанный на том, что вы думаете, а не на описании того, чего вы пытаетесь достичь.Если мы сделаем несколько шагов назад, то найдется более элегантное решение.
В общем, внедрение объектов в службы с сохранением состояния - плохой шаблон в 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
необходимо создать / уничтожить при запуске или остановке пакета, и он сделает ваш код намного чище.