Maven 提供了广泛的依赖模型。一个项目有一个 pom,这个 pom 指定了它对其他 pom 的依赖。这是可传递的,因此有一个依赖项可以下载一半的互联网。在 maven 中,您可以指定需要对编译类路径或运行时类路径的依赖。
在 OSGi 中,您应该创建一个可以在不同环境中使用的包。出于这个原因,bundle 是一个明确其依赖关系的 JAR。就像 Maven 一样,你可以让一个包依赖于另一个包(Require-Bundle)。但是,需要另一个捆绑包变得非常脆弱。
- 它倾向于创建大型依赖图
- 您很容易遇到需要使用不同版本的同一工件的情况
- 您需要很多,因为您通常只需要另一个捆绑包的一部分
- 您通常喜欢使用不同的实现
因此,OSGi 有一个基于功能 的本机依赖模型。包导出是一种能力。在 OSGi 中,Bundle A 不依赖于 Bundle B,但它依赖于 package b。 (并且包应该代表一个合约/API。)任何导出包 b 的包都将满足包 A。这种模型有很多优点,最大的优点是它不具有传递性。这为部署时间提供了极大的灵活性。
在 OSGi 中,一个关键目标是最大限度地减少依赖关系,并且只依赖于定义良好的 API,而不是实现,因此捆绑软件易于在许多不同的上下文中使用。
那么你如何在 maven 中构建它?
一般来说,您让 bnd 分析您的代码。然后它将创建一个清单,准确地表达你的包所依赖的包。
但是,开源中的大量代码的结构方式可能不仅仅依赖于 API。那么如何处理这些实现依赖呢?
使用嵌入依赖项选项,您从 maven pom 中拖入所有传递依赖项(可能很多)。我不会使用它。它很快但也很脏,因为你不知道你拖了什么。
一般来说,我会仔细设计捆绑包。因此,bnd 可以指定应包含构建路径上其他工件的哪些包。甚至还有一种方法可以让 bnd 从特定的命名空间中计算出需要什么:
Conditional-Package: aQute.lib.*
这在第一次很少能完美运行,你会发现你第一次运行时会错过一些东西,所以它需要一些迭代。但是,至少您知道捆绑包中的内容。