OSGi:在声明式服务组件激活方法中注册服务是否有效?

标签 osgi declarative-services

这是另一个问题的副本,但是从另一个问题复制:

我遇到了 Felix SCR 的问题,我收到了消息:

ServiceFactory.getService() 产生了一个循环

出现这种情况的原因是因为在激活方法中,调用它 ServiceAImpl(它提供 ServiceA),该服务注册另一个服务,调用它 ServiceB。

我有另一个服务组件,称之为 ServiceCImpl,它同时依赖于 ServiceA 和 ServiceB。通过 ServiceAImpl 注册 ServiceB,ServiceCImpl 已经满足,并且在激活 ServiceAImpl 的同一个调用中,调用了 ServiceCImpl 绑定(bind)方法。调用ServiceA的绑定(bind)方法时,检测到循环,组件初始化失败。

也许有一种方法可以让 SCR 等待绑定(bind) ServiceCImpl 或者我需要以不同的方式注册 ServiceB?

我猜不明白的是为什么Felix SCR会在ServiceAImpl的激活方法中激活ServiceCImpl。在激活方法退出之前,我不认为 ServiceCImpl 会被认为是满意的。也许这是在使用声明式服务的同时仍然直接向框架注册服务的问题?

还没有尝试过其他 SCR 实现,比如 Equinox 的版本,但我可能会尝试看看是否有区别,但也许有人知道这是 OSGi 的东西还是 Felix 的东西?

附加信息:至于为什么 ServiceB 不是服务组件...ServiceA 实际上有一个服务引用 0..n 用于另一个服务,将其称为 ServiceD。每次组件提供 ServiceD 接口(interface)时,都会使用相同的服务对象注册 ServiceB。通常 ServiceD 的同一个提供者可以提供 ServiceB,但其想法是使开发人员的整体接口(interface)更加简单,这样他们就不必提供多个服务接口(interface)(此外,ServiceB 有一些自动设置的属性,必须是手动完成,并且可能会错误地完成)。

最佳答案

出现这种情况的原因是 ServiceAImpl 是一个已加载的延迟组件,因此实际上 ServiceA 在组件被激活之前就已经注册了。但是,当出现另一个需要 ServiceA 的组件时,这会导致 ServiceAImpl 被激活。 ServiceAImpl 激活过程的一部分是注册 ServiceB,这会立即导致 ServiceCImpl 被激活。 FELIX-2368 中进行了更改,通过使大多数 SCR 操作同步来立即激活组件。

解决方法是使 ServiceAImpl 成为不需要的直接组件,因为如果没有任何服务需要该服务,则不应激活它。在这种情况下,激活方法在加载组件时完成,到需要它并绑定(bind)到另一个组件时就没有问题了。

关于OSGi:在声明式服务组件激活方法中注册服务是否有效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5718510/

相关文章:

java - OSGi DS 服务配置和 ServiceTracker

java - OSGi 'update' 命令;动态服务不会重启

java - 对 Karaf 的服务状态不满意(引用) - 错误在哪里? (OSGi、声明式服务、注释)

java - OSGi 类似于其他编程语言中的模块化

java - org.osgi.framework.BundleException : Could not find bundle: org. eclipse.equinox.console

java - 带有 ds 注释的一个目标服务的多个 PID

java - 为什么手动连接 OSGi 服务不是一个好主意?

jpa - Apache Aries 托管 JPA 支持哪些 JPA 提供程序?

java - 如何设置具有多个子项目的 Eclipse 项目 (OSGi-Bundle)

java - 关于如何在 Eclipse 4 中使用 IContextFunction 的示例