什么时候应该使用Import-Package,什么时候应该使用Require-Bundle?
OSGi允许通过Import-Package
来确定依赖关系,它仅连接一个包(从任意包导出)和Require-Bundle
,它们连接到特定命名包的导出。什么时候应该使用Import-Package,什么时候应该使用Require-Bundle?
在构建一个未开发的OSGi应用程序时,应该使用哪种方法来表示依赖关系?大多数软件包都是内部的,但是对外部(开源)软件包会有一些依赖关系。
我相信Require-Bundle
是一个Eclipse的东西(现在已经在OSGi规范中使它适应Eclipse)。 “纯粹的”OSGi方法是使用Import-Package
,因为它专门将软件包从提供它的软件包中分离出来。您应该声明您需要的功能(Java API由特定版本的特定软件包提供)的依赖关系,而不是来自哪些功能(这对您无关紧要)。这使捆绑的组合更加灵活。
JavaScript类比:这就像检测Web浏览器是否支持某个API,而不是根据用户代理字符串说明它是什么类型的浏览器来推断。
OSGi联盟的Peter Kriens在OSGi blog上对此有更多的评论。
可能唯一需要使用Require-Bundle
的情况是,如果您有拆分软件包,即分布在多个软件包中的软件包。拆分包当然非常不鼓励。
OSGi规范中定义了Require-Bundle和Import-Package;这两者没有“纯”的变体。 – AlBlue 2009-12-08 19:40:42
@AlBlue:更新了我的答案,使其更加清楚,虽然Require-Bundle在规范中,但它仅在Eclipse中兼容。 – Thilo 2009-12-09 00:51:09
我认为Thilo是对的。正如Peter Kriens在文章中提到的那样:“Require-Bundle具有难以否认的直观吸引力。”但它不必要地捆绑在一起。 在Java世界中,我会将它与IoC进行比较,并直接查找依赖关系。 一个例子取决于'commons-logging'软件包vs取决于'commons-logging' API软件包。在后一种情况下,您可以轻松地将'common-logging'软件包与适当的SLF4J适配器软件包进行交换,该软件包还可以输出commons-logging' API软件包,从而可以无缝地创建从“commons-logging”到SLF4J的桥梁。 – 2009-12-09 06:21:21
我相信导入包给你松散耦合,应该是首选。我在声明对不包含的包(如slf4j)的依赖性时使用它,并且可以根据需要交换实现。当依赖项是我控制的东西时,例如我自己的包,我使用Require-Bundle,因为无论如何,任何重要的更改都会经历我自己。
我不相信使用Import-Package更好,因为我使用bundle的默认期望是使用关联的公共API。因此,Require-Bundle更有意义。
该声明没有任何意义。您的理由是您将使用导入包而不是要求包的原因。处理公共API,不必担心由谁提供。你不用捆绑工作,你使用API。 – Robin 2012-01-18 21:07:03
赞成Import-Package over Require-Bundle。
要求束:
- 指定了明确的软件包(和版本)使用。如果一个请求包需要重构,并且一个包需要被移植到其他地方,那么依赖者将需要对其MANIFEST进行更改.MF
- 可让您访问该包的所有导出,无论它们是什么,无论您是否需要它们。如果零件你不需要有自己的依赖关系,你需要那些
- 束可以再出口
- 虽然气馁,允许使用拆分包的,即:跨多个包 传播包
- 可用于非代码依赖关系,例如:资源,帮助等。
导入级封装:
- 更松散的耦合,只有包(和版本)中详细说明,运行时找到所需的束
- 实际实现可以swaped出
- 从属软件包可以被软件包所有者移动到不同的软件包中
- 但是需要更低的粒度级别来维护更多的元数据(即:每个软件包名称)
对于导入包,如果您需要包的特定版本但包中实际包含版本,该怎么办? AFAIK,java包没有版本。 – 2015-08-25 14:39:24
Import-Package
应该会更好,因为,正如前面说的,你可以从一个包移到一个包另一个不改变现有客户的MANIFEST.MF
但是......
有一个实际的原因如果使用Eclipse开发捆绑软件,请使用Require-Bundle
:
Eclipse不使用包作为分辨率的单位。它使用包。也就是说,如果您使用一个包的一个包,Eclipse将编译您的包,而不会报告使用未从该包导入的其余包的任何问题。
你可能(你是人类)认为一切正常,并上传你的包进行部署,但是......你的包会在运行时中断。
我很确定,因为这个问题发生了(对我来说)今天。
好的解决方案是更改Eclipse类路径容器,但是......如果这不会完成......您可以决定避免这种需要捆绑而不是软件包的问题,并支付所提到的价格(捆绑之间没有向后兼容的代码移动)。
避免导入包装。由于软件包提供了软件包之间的多对多关系,它们很容易产生难以检测和避免的依赖性循环。
另一方面,Require-Bundle引用单个bundle,通过简单的构建时间检查使得依赖图免受循环影响。 通过Require-Bundle,构建具有较低抽象级别的分层体系结构要容易得多。
从http://eclipsesource.com/blogs/2009/07/14/why-i-cant-recommend-using-import-package/:“Look,Require-Bundle是在Eclipse中用于一段时间,主要是出于遗留原因。我们不建议再使用它。如果您想要软件包之间的松散耦合,导入包更好。但是,请注意疼痛分割包可能导致的问题。“ – 2009-12-08 09:47:54