我应该何时使用Import-Package,何时应该使用Require-Bundle?

时间:2009-12-08 09:36:52

标签: osgi

OSGi允许通过Import-Package确定依赖关系,Require-Bundle只连接单个包(从任何包中导出),以及{{1}},它连接到特定命名包的导出。

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

6 个答案:

答案 0 :(得分:49)

我相信Require-Bundle是一个Eclipse的东西(现在已经在OSGi规范中使其适应Eclipse)。 “纯”OSGi方法是使用Import-Package,因为它专门将包与提供它的包解耦。您应该声明依赖于您需要的功能(特定软件包的特定版本提供的Java API)而不是该功能的来源(这对您来说无关紧要)。这使捆绑的组成更加灵活。

JavaScript类比:这类似于检测网络浏览器是否支持某个API,而不是根据用户代理字符串说明它是什么类型的浏览器。

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

可能唯一需要使用Require-Bundle的情况是,如果您有拆分包,那么这是一个分布在多个包中的包。当然,非常不鼓励拆分包。

答案 1 :(得分:14)

支持Import-Package over Require-Bundle。

Require-Bundle:

  • 指定要使用的显式包(和版本)。如果需要重构一个requirde包并将包移到别处,那么dependents将需要更改他们的MANIFEST.MF
  • 使您可以访问捆绑包的所有导出,无论它们是什么,无论您是否需要它们。如果您不需要的部件具有自己的依赖关系,则需要
  • 捆绑包可以重新导出
  • 虽然不鼓励,但允许使用拆分包,即:分布在多个包中的包
  • 可用于非代码依赖,例如:resources,Help等。

导入级封装:

  • 松散耦合,仅指定包(和版本),运行时查找所需的包
  • 可以跳出实际的实现
  • 包所有者
  • 可以将相关包移动到不同的包中
  • 但需要更低的粒度级别维护更多元数据(即:每个包名称)

答案 2 :(得分:5)

我相信Import-Package可以让你更宽松,应该是首选。我在声明对我不拥有的包的依赖时使用它,例如slf4j,我可以按照自己的意愿交换实现。当依赖是我可以控制的东西时,我使用Require-Bundle,比如我自己的bundle,因为无论如何任何重要的改变都会经历过我自己。

答案 3 :(得分:0)

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

但是...

如果您使用Eclipse开发捆绑包,则有一个实际的理由使用Require-Bundle

Eclipse不会将包用作解析单位。它使用捆绑包。也就是说,如果您使用捆绑包中的一个包,那么Eclipse会编译您的捆绑包,而不会报告使用未从该捆绑包导入的其他包的任何问题。

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

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

好的解决方案是更改Eclipse类路径容器,但是......如果不这样做......你可以决定避免这种需要捆绑的问题,而不是包,支付上述价格(捆绑之间没有向后兼容的代码移动。)

答案 4 :(得分:0)

避免使用Import-Package。 由于软件包在bundle之间提供了多对多关系,因此它们很容易出现难以检测和避免的依赖循环。

另一方面,

Require-Bundle引用单个bundle,通过简单的构建时检查使依赖图免受周期的影响。 使用Require-Bundle,可以更容易地构建具有较低抽象级别的分层架构。

答案 5 :(得分:-1)

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