什么时候应该使用Import-Package,何时使用Require-Bundle?

OSGi允许通过Import-Package来确定依赖关系, Import-Package只连接一个包(从任何包导出)和Require-Bundle ,它连接到特定的命名包的导出。

在构build一个新的OSGi应用程序时,我应该使用哪种方法来表示依赖关系? 大多数捆绑包都是内部的,但是对外部(开源)捆绑包会有一些依赖关系。

我相信Require-Bundle是Eclipse的东西(现在已经在OSGi规范中使它适应Eclipse)。 “纯粹的”OSGi方法是使用Import-Package ,因为它特别将软件包从提供软件包的软件包中分离出来。 你应该声明依赖于你需要的function(某个特定版本的某个软件包提供的Java API),而不是来自哪个function(对你来说不重要)。 这使得捆绑的组合更加灵活。

JavaScript的比喻:这就像检测一个Web浏览器是否支持某个API,而不是从用户代理string表示什么样的浏览器。

OSGi联盟的Peter Kriens在OSGi博客上对此有更多的评论。

可能唯一需要使用Require-Bundle是如果你有拆分包,这是一个分布在多个包中的包。 拆分软件包当然是非常灰心的。

赞成导入包在需求捆绑。

需要束:

  • 指定要使用的显式包(和版本)。 如果一个需求包需要被重构,而一个包被移动到其他地方,那么依赖者需要修改MANIFEST.MF
  • 使您可以访问软件包的所有导出,而不pipe它们是什么,也不pipe您是否需要它们。 如果你不需要的部分有自己的依赖关系,你将需要这些
  • 捆绑包可以被重新导出
  • 虽然不鼓励,但允许使用拆分包,即:分散在多个包中的包
  • 可以用于非代码依赖,例如:资源,帮助等

import包装:

  • 松散耦合,只指定包(和版本),并且运行时find所需的包
  • 实际的实现可以被删除
  • 软件包所有者可以将相关的软件包移动到不同的软件包中
  • 但是需要更低的粒度级别来维护更多的元数据(即:每个包名称)

我相信import包裹给你松散耦合,应该是首选。 当我声明依赖于我不拥有的包(如slf4j)时,我使用它,并且可以根据需要交换实现。 当依赖项是我自己控制的东西时,例如我自己的bundle,我使用Require-Bundle,因为无论如何,任何重要的改变都会经历我自己。

避免导入包装。 由于软件包提供了软件包之间的多对多关系,因此很容易产生难以检测和避免的依赖性循环。

另一方面,Require-Bundle引用单个bundle,通过一个简单的构build时间检查,使依赖关系图免受循环影响。 使用Require-Bundle,构build具有较低抽象级别的分层体系结构将变得更加容易。

Import-Package应该会更好,因为如前所述,您可以将包从一个包移动到另一个包,而无需更改现有客户端的MANIFEST.MF

但…

如果您使用Eclipse来开发Require-Bundle那么使用Require-Bundle有一个实际的原因:

Eclipse不要使用包作为分辨率的单位。 它使用包。 也就是说,如果您使用一个包的一个包,Eclipse将编译您的包,而不报告使用未从该包导入的其余包的任何问题。

你可以(你是人类)认为一切正常,并上传你的包进行部署,但是…你的包会在运行时中断。

我很确定,因为这个问题发生了(对我!)今天。

好的解决scheme是更改Eclipse的classpath容器,但是如果这样做不能完成…你可以决定避免这种需要捆绑的问题,而不是软件包,支付所提到的价格(没有向后兼容代码之间的移动)。

我不相信使用Import-Package更好,因为使用bundle的默认期望是使用关联的公共API。 为此,Require-Bundle更有意义。