【问题标题】:OSGi: Do DS-service consumers get notified synchronously when a certain service become availableOSGi:当某个服务可用时,DS-service 消费者是否会同步收到通知
【发布时间】:2023-03-21 03:55:01
【问题描述】:

我有一个 IFoo 接口的 DS 服务使用者:

@Component
public class IFooListener {

    @Reference(bind = "bind",
               unbind = "unbind",
               referenceInterface = IFoo.class,
               cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE,
               policy = ReferencePolicy.DYNAMIC)
    public static final Map<String, IFoo> allServices = new ConcurrentHashMap<>();

    protected void bind(IFoo service, Map<String, String> properties) {
    ....
    }
    ....
}

我有这样注册的 IFoo 服务:

BundleContext ctx = FrameworkUtil.getBundle(IFooListener.class).getBundleContext();
Properties properties = new Properties();
....
ServiceRegistration managementSrv = ctx.registerService(IFoo.class.getName(), iFooImpl, properties);

我想知道的是,是否保证当 ctx.registerService(...) 方法返回时,所有当时已经可用的 DS 消费者都会被通知 IFoo 服务已注册? 这是 osgi-implementation 特定的东西吗?或者这是 DS 规范的一部分?

【问题讨论】:

  • 您应该指出您使用的注释,因为有多个注释。这些绝对不是标准的 OSGi 注释。作为答案,在系统中依赖此类保证是非常糟糕的做法。

标签: java osgi declarative-services


【解决方案1】:

我在规范中找不到确切的答案。但是,我刚刚检查了 Felix SCR 的代码,发现它没有打开新线程。它实现了 ServiceListener 接口(因为它总是必须处于最深层次),幸运的是 ServiceListener 的 javadoc 说 addService 是同步调用的。

简而言之:bind方法在Felix SCR中同步调用。

【讨论】:

  • 好的,所以 SCR 实现了 ServiceListener 并根据 OSGi 规范“当一个 ServiceEvent 被触发时,它被同步传递给一个 ServiceListener。”。所以以某种方式,我们确定当 ctx.registerService() 返回时,SCR 已经得到通知。但这是否意味着 SCR 已通知所有托管组件?我在规范中没有找到这个,所以我猜这是特定于实现的。你是对的,至少现在对菲利克斯来说是正确的。但也许未来 Felix 开发人员决定以异步方式通知组件?
  • 是的。这就是我的意思。现在 Felix SCR 不会启动新线程。如果我是你,我会使用 ServiceTracker。我从来没有觉得有必要使用 DS 的多个动态引用,因为它基本上是一个 ServiceTracker。这就是 [ECM][1] 没有这种引用类型的原因。 [1]:everit.org/ecm/index.html
  • 换句话说:不,不保证。
猜你喜欢
  • 2015-01-02
  • 1970-01-01
  • 1970-01-01
  • 2021-06-23
  • 1970-01-01
  • 1970-01-01
  • 2013-12-29
  • 1970-01-01
  • 2018-07-02
相关资源
最近更新 更多