当我们在1998年开始使用OSGi时,我们有一些明确的要求,但当然,对于它会产生什么没有清晰的认识。因此,我们开始明确地对我们拥有的需求和功能进行建模:包。导入包需要一项功能,而该功能由导出包提供。
2003年,Eclipse希望开始使用OSGi,但他们需要一个工具来需要另一个捆绑包,他们不喜欢导出和导入所有软件包的想法。实际上,当时他们没有看到软件包的好处。为了满足他们的需求,我们添加了Require-Bundle和Fraction-Host(他们的另一个愿望,结果证明不是那么好。
在我们使用这些扩展指定OSGi 4.x之后,我们开始考虑一个存储库,Richard开发了Oscar Bundle Repository。通过分析OSGi 4.0中新标头的情况,很明显,Import-Package的实现看起来很像Require-Bundle,甚至类似于Fraction-Host处理。
2006年,Richard S. Hall和我写了RFC 112,提出了一个更通用的模型,它捕获了现有依赖模型的语义,但并不特定于每种类型的需求。即,对于框架解析器,Import-Package 和 Require-Bundle 仅在命名空间上有所不同。将 Import-Package 视为通用要求,将 Export-Package 视为通用功能,使得存储库模型变得非常简单。更好的是,它是可扩展的,因为我们总是可以添加更多的命名空间。这使得解析程序完全独立于实际使用的命名空间。
经过一番非常激烈的讨论,OSGi核心平台专家组决定接受基本思路,并制定了需求和能力规范。虽然这最初是存储库的模型,但它对框架本身非常有用。因此,我们决定根据此模型调整现有规格。OSGi 4.3 在内部将 Import-Package、Export-Package、Require-Bundle 等建模为资源(捆绑包)的需求和功能。为了向后兼容,我们保留了现有的标头,但它们在内部转换为需求和功能。
最后是你问题的答案。随着时间的推移,OSGi规范增加了越来越多的命名空间。命名空间类似于要求和功能的类型。它定义了该命名空间中功能的一组属性的语义。要求是对那些属性断言的筛选器表达式。资源具有一组功能,这些功能在满足其所有要求时提供给运行时。冲突解决程序的任务是查找一组资源,这些资源都对彼此的功能和运行时提供的功能感到满意。
例如,我们添加了命名空间,该命名空间准确定义了捆绑包可以在哪个 VM 上运行。我们添加了对外部程序(如服务组件运行时 (SCR))的依赖项进行建模的命名空间。大多数SCR组件不需要SCR本身的任何封装,我们努力使它们尽可能独立。但是,SCR 组件将毫无用处,除非运行时中的某个捆绑包提供了 SCR 功能。请注意,这不能使用 Require-Bundle,因为 SCR 有多个实现。我认为大约有20个命名空间。每个命名空间都在一个类中定义。osgi.ee
osgi.extender
Namespace
此模型为 OSGi 提供了许多优点:
-
内聚力尽管规范添加了许多命名空间,但解析程序实现从未更改过,因为它们在泛型模型上工作。
-
细粒度OSGi 捆绑包的独特之处在于它们以非常细粒度的方式描述其依赖关系。我所知道的所有模块系统都倾向于使用简单的模块到模块依赖关系,不允许替换。
-
灵活由于框架重新定义了捆绑包之间的依赖关系,因此可以在运行时利用这些依赖关系。例如,在 OSGi enRoute 中,我将一个捆绑包链接到遍历这些运行时连接的网页。
我个人认为OSGi的需求和能力模型是它最保守的秘密之一。据我所知,它可以用于许多领域,以改进软件工程领域的许多开发项目。
这个问题中唯一令人失望的部分是,我认为我们已经在Core规范中很好地描述了这一点?:-)