【问题标题】:OSGi: What happens when an imported service is stopped while the service is still runningOSGi:在服务仍在运行时停止导入的服务会发生什么
【发布时间】:2013-12-20 14:47:01
【问题描述】:
假设我正在使用一个service A,它是在另一个service B 中导入的。当B 正常运行时(当然A 处于活动状态),如果service A 被卸载而service B 仍在运行,会发生什么情况?
Service A -> Service B
如果我使用ServiceReference、ServiceTracker 和DS,会有什么不同的场景?
【问题讨论】:
标签:
service
osgi
declarative-services
【解决方案1】:
首先:OSGi 的优点之一是框架和标准服务的行为被明确规定。这些规范可以从OSGi Alliance web site 下载,或者,如果您不喜欢阅读 PDF,可以订购打印。您提出的问题在这些规范中得到了完美的回答。
总而言之:当服务未注册时:
-
ServiceReference 对象保持原样。但是,对 ServiceReference.getService() 的调用将返回 null。请注意,使用ServiceReferences 时,您应该释放对通过getService() 检索到的实际服务对象的所有引用,这通常需要对服务进行某种跟踪。
- 为
ServiceTracker 调用ServiceTracker.remove。这通常会导致在ServiceTracker 或定义的ServiceTrackerCustomizer 上调用removedService()。
- 对于 DS,为引用的服务调用定义的
unbind 方法(如果指定)。此外,如果使用的服务的基数表明该服务是强制性的,则根据替代服务的可用性和为服务定义的策略,使用的服务也可能被取消注册,甚至可能被停用或激活新的实例。
【解决方案2】:
当一项服务在 OSGi 中未发布时,会向当前使用该服务的所有捆绑包发送一个事件,告诉他们应该停止使用它。
如果您使用的是 DS,您的 unbind 方法将被调用。当它被调用时,您应该尽最大努力尽快停止使用该服务。但归根结底,OSGi 是一个协作系统,它不能强制您发布服务。但是,如果您不这样做,则可能会导致问题,例如服务发布者将不会被完全垃圾收集。您最终会破坏 OSGi 平台的动态,可能会造成内存泄漏等。
如果你使用ServiceTracker,那么removedService方法会被调用,你需要以同样的方式响应。但是我不是在另一个问题中告诉你不要使用ServiceTracker吗? ;-)
如果您使用ServiceReference,则需要显式注册ServiceListener 才能接收这些事件。这就是为什么你真的真的在你获得更多经验之前不应该使用这个低级 API(一旦你有了这种经验,你无论如何都不想使用它!) .