OSGi:导入-包/导出-包和需求-能力/提供能力有什么区别?

2022-09-04 07:46:15

我目前正在使用OSGi框架,但我对一些概念有一个问题,这些概念对我来说不是100%清楚。我自己搜索过它,但我找不到一个像样的答案来清楚地解释它。

在捆绑包中,他的清单标头 2 使用的标头是 和 。这些名称不言自明:对某个软件包的需求和某个软件包的提供。为了获取该软件包(或提供该软件包),必须将完整的捆绑包安装在需要导入的框架中。Import-PackageExport-Package

但是,我们来到了模型的部分。这实际上可以与 和 标头执行相同的操作。此模型还有标头:和 。同样,这些代表要求某事和提供某物。Requirements-CapabilitiesImport-PackageExport-PackageRequirements-CapabilityRequire-CapabilityProvide-Capability

我知道该模型只是在OSGi规范的开发中引入的。无法准确找到它在哪一年和哪个版本呈现。Requirements-Capability

  • 为什么将其添加到规范中?我没有看到它比/已经提供的东西更多:在其他包/捆绑包上创建依赖关系?ImportExport-package

  • 有人能让我更好地理解这两组概念之间的区别(优点和缺点)吗?


答案 1

当我们在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.eeosgi.extenderNamespace

此模型为 OSGi 提供了许多优点:

  • 内聚力尽管规范添加了许多命名空间,但解析程序实现从未更改过,因为它们在泛型模型上工作。
  • 细粒度OSGi 捆绑包的独特之处在于它们以非常细粒度的方式描述其依赖关系。我所知道的所有模块系统都倾向于使用简单的模块到模块依赖关系,不允许替换。
  • 灵活由于框架重新定义了捆绑包之间的依赖关系,因此可以在运行时利用这些依赖关系。例如,在 OSGi enRoute 中,我将一个捆绑包链接到遍历这些运行时连接的网页。

我个人认为OSGi的需求和能力模型是它最保守的秘密之一。据我所知,它可以用于许多领域,以改进软件工程领域的许多开发项目。

这个问题中唯一令人失望的部分是,我认为我们已经在Core规范中很好地描述了这一点?:-)


答案 2

要求和功能模型是导入/导出包模型的扩展。实际上,您可以将包导入表示为要求,将包导出表示为功能。

导出/导入包允许松散耦合。导出 API,客户端将其导入。这样,客户端只需要了解 API,即可实现松散耦合。

在稍后阶段,当您从捆绑包中组装应用程序时,这种松散耦合使得该过程难以自动化。

如果您只是将客户端捆绑软件提供给解析程序,那么它只能自动找到您需要提供 API 的捆绑软件。如果 API 的实现位于不同的捆绑包中,则解析器无法知道您需要它。

这就是需求可以提供帮助的地方。让我们以 HTTP 白板模型为例。想要发布 servlet 的捆绑包需要导入 servlet api 包,但也需要表达它想要 osgi http 白板的实现。

这可以通过命名空间=“osgi.implementation”,name=“osgi.http”,version=“1.1.0”的要求来表示。由于这很难手动编写,因此有注释支持。

@HttpWhiteboardServletPattern("/myservlet")
@Component(service = Servlet.class)
public class MyServlet extends HttpServlet {
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
            throws IOException {
        resp.getWriter().println("Hello");
    }
}

注释@HttpWhiteboardServletPattern间接转换为上述要求。

因此,当您使用此类构建捆绑包时,它将导入 servlet api 包,并且还需要 http 白板实现。

现在,如果您查看像 felix http 服务这样的实现捆绑包,您会发现它为白板 impl 提供了功能。

因此,如果你有一个带有捆绑包的OSGi存储库,servlet API和felix http服务。然后,解析器可以为您提供一个完整的应用程序,如果您只提供捆绑包。


推荐