OSGi 中的服务引用
一旦从捆绑上下文中检索到 OSGi 服务的实例,该服务停止时该实例是否会失效?
我的初步测试表明,即使服务包停止后,服务实例也可以使用,这与我对 OSGi 动态特性的理解相矛盾。
我想这可以归结为从 OSGi 容器中的另一个包检索服务(通过 ServiceTracker)实际上做了什么,它是创建一个新实例还是为您提供一个指向在容器中注册的实例的指针?
服务停止后使用服务实例是否有危险?
Once an instance of an OSGi service is retrieved from the bundle context does it become invalidated when the service is stopped?
My initial tests show that the service instance can be used even after the service bundle is stopped, which contradicts my understanding of the dynamic nature of OSGi.
I suppose this boils down to what retrieving a service (via ServiceTracker) from another bundle in the OSGi container actually does, does it create a new instance or does it give you a pointer to the instance that is registered in the container?
Are there any dangers in using the service instance after the service has been stopped?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
这是一个非常好的问题,因此我深入研究了规范以寻找明确的答案。事实证明,有一整节都在讨论这个问题 - 请参阅从 OSGi 服务平台核心规范,第 4 版,版本 4.2。
根据规范回答您的问题:
并防止潜在问题:
该规范还提供了一些如何最大限度地减少过时引用的后果的提示。
This is a very good question so I digged into the specification in search for a definitive answer. It turns out that there is a whole section talking about this problem - see section 5.4 Stale References starting on page 132 of OSGi Service Platform Core Specification, Release 4, Version 4.2.
To answer your question according to the specification:
And to prevent potential problems:
The specification also gives some tips how to minimize the consequences of stale references.
你是对的,它与 OSGi 的动态本质相矛盾。我认为,尽管 OSGi 容器和服务本身的不同实现可能表现不同,但不能保证该服务可用。
例如,如果服务是使用 Spring DM 创建并注册的,那么检索到的服务实际上是底层实现的基于 Spring 的代理,并且该实现仍然可能消失。因此,直接引用实现的服务引用可以防止该对象被删除,而基于代理的引用则不会。
You are right in that it is contradictory to the dynamic nature of OSGi. I believe that there is no guarantee that the service will be available, although different implementations of OSGi containers and services themselves may behave differently.
For example, if the service was created and registered with Spring DM, then the service retrieved is actually a Spring based proxy to the underlying implementation, and the implementation can still disappear. Thus a service reference that refers directly to an implementation may keep that object from being removed, whereas the proxy based reference will not.
OSGi 规范指出:
因此,您不应该能够从已停止的捆绑包中获取服务。但从技术上讲,它是可以使用的,至少只要您持有对服务对象的引用(没有人可以从您手中夺走它,并且它不会被 GC 回收)。但我不认为使用该服务是省钱的。它可能依赖于其他捆绑包资源,这些资源在捆绑包停止后不可用。
The OSGi specification says:
So you shouldn't be able to get a service from a stopped bundle. But technically it may be possible to use it, at least as long as you hold a reference to the service object (nobody can take it away from you and it will not be GC'd). But I don't think that it is save to use the service. It may depend on other bundle resources, that are not available after the bundle has stopped.
不,引用本身不会失效。只要容器内有东西保存着它,它就无法被 GC 回收。
然而,它是否仍然有用,仅取决于服务实现本身,而不是容器。
规范本身表明不应保留此类引用,但实施者应注意正确实施规范;意味着不存在矛盾,只是您可以实现和部署未按照规范正确运行的捆绑包。
容器不会创建新的服务实例,除非涉及 ServiceFactory(请参阅规范)。查找服务应该始终为您提供指向容器中已注册实例的指针。
这仅取决于服务的实现;但是,通过在捆绑包中执行此操作,您会自动创建一个不符合规范的捆绑包。
在实践中,许多服务都是为了释放资源和引用而实现的,并且将不再正确响应。
No, the reference itself does not become invalidated. As long as something within the container is holding it, it can also not be GC'ed.
However, whether or not it will be still useful, depends only on the service implementation itself, not the container.
The specifications itself indicate that such references shouldn't be held, but it's up to the implementer to take care for implementing the specifications correctly; means there is no contradiction, there is only the fact that you can implement and deploy bundles which don't behave correctly according to the specifications.
The container does not create new instances of services, except if there is a ServiceFactory involved (see specs). Looking up a service should always give you a pointer to the registered instance in the container.
That only depends on the service implementation; however, by doing so in a bundle, you automatically create a bundle that is not conform with the specs.
In practice, many services are implemented to release resources and references and will not respond properly any longer.
关于您的问题,服务停止后使用服务实例是否有危险。引用 4.2 核心规范(5.4 陈旧引用):
我不想在这里引用规范的整个部分,但以下句子很好地讨论了使用陈旧引用的危险:
Regarding your question whether it is dangerous to use a service instance after the service has been stopped. To cite from the 4.2 core spec (5.4 Stale References):
I dont want to cite the whole section of the spec here, but the following sentences are a good discussion about the danger of using stale references:
服务参考永远不应该被保留作为参考。您应该始终在运行时查找服务。这会将您与 OSGI api 联系起来,但这并不总是需要的。
看看
- OSGI服务跟踪器
- OSGI声明服务
- OSGI 蓝图
- 弹簧DM
- 豌豆莓
- iPojo
都为您处理动态,其中大多数没有 OSGI api 可供使用。
问候,
林·托伦
A service reference should never be kept as a reference. You should always look up a service at runtime. This ties you to the OSGI api however, whihc is not always wanted.
Have a look at
- OSGI serviceTracker
- OSGI declarative services
- OSGI BluePrint
- Spring DM
- Peaberry
- iPojo
which all take care of the dynamism for you, most of them with no OSGI api to use.
Regards,
Leen Toelen