我试图了解OSGi服务。我一直在问自己的主要问题是:使用服务而不是使用捆绑包及其导出的包有什么好处?
据我所知,这似乎是概念 后期绑定 与它有关。 Bundle依赖关系在bundle start处连接在一起,所以我猜它们非常固定。但随着服务似乎几乎相同。捆绑包启动并注册服务或绑定到服务。当然,服务可以随时出入,你必须跟踪这些机会。但核心理念似乎与我不同。
另一个方面似乎是服务更灵活。一个特定接口可能有许多实现。另一方面,对于特定的导出包也可以有许多不同的实现。
在另一篇文章中,我读到使用导出包的缺点是它们使应用程序比服务更脆弱。作者写道,如果从依赖图中删除一个包,则不再满足其他依赖关系,因此可能会对整个图形造成多米诺骨牌效应。但是如果服务脱机会发生同样的情况吗?对我而言,服务依赖性似乎并不比bundle依赖性更好。
到目前为止,我找不到可以清楚地描述为什么服务比通过导出和导入包公开功能更好的博客文章,书籍或演示文稿。
总结我的问题:
使用OSGi服务使其优于导出和导入包的主要好处是什么?
加成
我试图收集有关此问题的更多信息,并在包和服务的普通导出/导入之间进行某种比较。也许这会帮助我们找到一个令人满意的答案。
启动/停止/更新
捆绑(因此包)和服务都可以启动和停止。除此之外,他们可以更新。服务也与捆绑生命周期本身有关。但在这种情况下,我只是说你可以启动和停止服务或捆绑(以便导出的包“消失”)。
跟踪变化
ServiceTracker和BundleTracker使跟踪和响应捆绑和服务可用性的变化成为可能。
与其他捆绑包或服务的特定依赖关系。
如果要使用导出的包,则必须导入它。
Import-Package: net.jens.helloworld
将 net.jens.helloworld 提供服务我还需要导入包以获得接口。
因此,在这两种情况下,它们都会与某种或多或少的特定包装形成某种“紧密耦合”。
能够拥有多个实现
特定包可以通过多个包导出。可能有一个包 net.jens.twitterclient 由bundle A和bundle B导出。这同样适用于服务。界面 net.jens.twitterclient.TwitterService 可以由捆绑A和B发布。
总结一下这里的简短比较(导出包/服务):
- 是的是的
- 是的是的
- 是的是的
- 是的是的
所以没有区别。
此外,似乎服务增加了更多的复杂性并引入了另一层依赖关系(参见 图片 下面)。
替代文字http://img688.imageshack.us/img688/4421/bundleservicecomparison.png
因此,如果导出的包和服务之间没有真正的区别,使用服务的好处是什么?
我的解释:
服务的使用似乎更复杂。但服务本身似乎更轻巧。如果您启动/停止整个捆绑包或者您只是启动和停止特定服务,那么它应该是(在性能和资源方面)的差异。
从架构的角度来看,我也猜测捆绑包可以被视为应用程序的基础。在启动和停止捆绑方面,基础不应经常更改。该功能由该包的服务在“捆绑层”上方的某种动态层中提供。这个“服务层”可能会经常变化。例如,如果数据库脱机,则取消注册用于查询数据库的服务。
你怎么看?我是开始得到服务的全部还是我还在想错误的方法?是否有我遗漏的东西会使服务比出口包更具吸引力?