2 回答
TA贡献1906条经验 获得超10个赞
对我来说,这看起来像是根据您认为答案的内容提出问题,而不是描述您想要实现的目标。如果我们退后几步,那么存在更优雅的解决方案。
通常,将对象注入有状态服务是 OSGi 中的一种糟糕模式。它迫使您对生命周期非常小心,并冒着内存泄漏的风险。从示例代码看来,您真正想要的是让您的消费者在事件管理主题上发生事件时得到通知。最简单的方法是从等式中删除 XyzHandler 并使消费者成为这样的事件处理程序:
@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;
}
}
如果你真的不想让你的ConsumeranEventHandler那么将消费者注册为服务并使用白板模式让它被一个人接收仍然会更容易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在启动或停止包时跟踪需要创建/销毁的内容,并使您的代码更清晰。
TA贡献1784条经验 获得超2个赞
听起来您的服务需要是原型范围服务。这是在 Core R6 中引入的。来自 Compendium R6 的 DS 1.3 包括对组件作为原型范围服务的支持。
但是 DS 1.2 早于 Core R6,因此不知道或不支持原型范围服务。
添加回答
举报