使用 SpringSource Application Platform 的 provisioning repository

工程 | Andy Wilkinson | 2008年5月9日 | ...

SpringSource Application Platform 的主要优势之一是它能够按需配置依赖项。这样做有两方面的好处:它确保了平台的内存占用尽可能小,并且允许在部署应用程序时无需将所有依赖项封装在一个庞大的部署单元中(例如 WAR 文件)。要利用这些功能,您需要了解平台的 provisioning repository,本博客旨在提供这方面的说明。

provisioning repository 在哪里以及它是如何工作的?

默认情况下,平台的 provisioning repository 位于安装根目录下的 repository 目录中:Directory structure of the provisioning repository 如您所见,主要有三个目录:bundlesinstalledlibrariesinstalled 供平台内部使用,所以我们这里重点关注 bundleslibraries 目录。每个目录都包含多个子目录以区分不同类型的依赖项。
  • ext 包含随平台提供但不属于平台本身的外部依赖项。
  • subsystems 包含构成平台的所有子系统。
  • usr 最初是空的,旨在包含用户添加的依赖项,即您的应用程序依赖但平台尚未提供的任何东西。
平台在初始启动期间会搜索 repository 目录结构以查找 bundle 和 library。我将在本文后面讨论如何配置这种搜索。当在 repository 中找到 bundle 和 library 时,其符号名称、导出的包等的详细信息会被添加到 repository 的内存索引中。扫描完成后,内存索引会缓存到磁盘。最大限度地缩短平台的启动时间是我们开发期间的优先事项。这种缓存允许平台在启动期间节省一些时间:除非检测到 repository 的内容已更改,否则可以跳过扫描。

运行时 provisioning

在纯粹的 OSGi 环境中,bundle 的依赖项只能由环境中已安装的其他 bundle 来满足。例如,如果尚未安装导出 org.apache.commons.dbcp 包的 bundle,则安装并启动导入该包的 bundle 将会失败。这对于用户来说确实很麻烦,因为他们必须手动安装一个 bundle 的所有依赖项。值得庆幸的是,SpringSource Application Platform 通过按需动态安装依赖项显著改进了这一点。

当平台启动已部署的应用程序时,其 bundle 会安装到 Equinox 中。然后平台会向 Equinox 请求所有 bundle 的未满足依赖项列表,并尝试满足它们。让我们通过一个简单的示例场景来分析这个过程。

  1. 一个导入 org.apache.commons.dbcp 的 bundle 由平台安装到 Equinox 中。
  2. 平台向 Equinox 请求该 bundle 的未满足依赖项,并被告知导入 org.apache.commons.dbcp 无法满足。
  3. 平台在其 provisioning repository 索引中搜索导出 org.apache.commons.dbcp 的 bundle。
  4. 平台将导出 org.apache.commons.dbcp 的 bundle 安装到 Equinox 中。
  5. 满足了原始 bundle 的依赖项后,平台成功启动了原始 bundle。
我们希望这能让我们的用户的生活更轻松:只要您的应用程序的依赖项对平台可用,您就可以简单地部署您的应用程序然后开始!无需花费大量时间手动安装应用程序的所有依赖项。这个过程的一个巨大优点是依赖项仅在需要时才安装。您可以向 provisioning repository 添加任意数量的 bundle,而对平台的内存占用几乎没有影响。

如果平台无法从其 repository 满足某个依赖项,则会生成一条日志消息,详细说明无法满足的依赖项。有了这些信息,您就可以使用 SpringSource Enterprise Bundle Repository 来获取您需要的东西。我们希望 repository 能够提供尽可能完整的 bundle 集:如果您需要某个依赖项但它不可用,请告知我们

向 provisioning repository 添加条目

您已经下载了一个或两个依赖项,现在想将它们添加到平台中。您只需将它们复制到 repository 中相应的目录即可。例如,一个新的 bundle 通常会添加到 repository/bundles/usr 目录,一个新的 library descriptor 通常会添加到 repository/libraries/usr 目录。

如上所述,平台使用其 provisioning repository 的内存索引,该索引在启动期间填充。除此之外,平台在部署应用程序时还会检查其对 repository 的视图是否最新。当您想要安装带有新依赖项的应用程序时,只需将依赖项复制到 repository 中相应的位置,然后部署您的应用程序即可。在部署处理过程中,平台会注意到 repository 已更新并刷新其视图。这意味着您无需在每次安装带有新依赖项的应用程序时花费时间重新启动平台。

在不同安装之间共享 provisioning repository

平台在 provisioning repository 中搜索条目的位置可以轻松配置以满足您的需求。例如,多个平台实例可以共享部分或全部 provisioning repository,因此您无需浪费精力在不同平台安装之间维护重复的 bundle 集。

平台在创建其 provisioning repository 时扫描的位置可以在 config/platform.config 文件中配置。在没有任何特定配置的情况下使用的默认配置是:


"provisioning" : {
    "searchPaths": [ 
        "repository/bundles/subsystems/{name}/{bundle}.jar",
        "repository/bundles/ext/{bundle}",
        "repository/bundles/usr/{bundle}",
        "repository/libraries/ext/{library}",
        "repository/libraries/usr/{library}"
    ]
}

任何相对路径都被平台解释为相对于其安装根目录,但也支持绝对路径。搜索路径中花括号内的条目只是通配符,例如,subsystems 搜索路径 repository/bundles/subsystems/{name}/{bundle}.jar 将在 subsystems 目录的任何直接子目录中找到名称以 .jar 结尾的任何文件。

希望您可以看到,在不同平台之间共享部分或全部 provisioning repository 是一个微不足道的更改。例如,要让平台在其自身的 subsystemsext 目录中以及文件系统根目录中名为 shared-bundles 的目录中进行搜索,您只需将以下 JSON (JavaScript Object Notation) 代码片段添加到 platform.config 文件中:


"provisioning" : {
    "searchPaths": [
        "repository/bundles/subsystems/{name}/{bundle}.jar",
        "repository/bundles/ext/{bundle}",
        "/shared-bundles/{bundle}",
        "repository/libraries/ext/{library}",
        "repository/libraries/usr/{library}"
    ]
}

通过使用此配置来配置两个或更多平台安装,可以使它们共享 /shared-bundles 中的 bundle。这可以很容易地更进一步,将所有搜索路径配置为指向共享位置,这样您就根本不需要管理每个平台的 provisioning repository 了。

下一步是什么?

我们计划通过提供一些工具或脚本来简化从同一组二进制文件运行多个平台实例。这些工具或脚本将为您完成大部分工作,提供一套合理的默认配置,您可以根据您的特定需求进行调整。

我们还打算通过允许平台配置为在尝试满足依赖项时可选地搜索远程 repository,来结合平台按需配置和 SpringSource Enterprise Bundle Repository 的强大功能。如果在远程 repository 中找到了依赖项,平台将自动处理其下载和安装。希望这能让开发人员的生活更轻松,尤其是在应用程序开发的初始阶段,因为新依赖项会定期添加。

在我们开发上述增强功能以及平台本身时,我们很想听听您的建议:请随时在本博客文章下发表评论、提交 JIRA,或在我们的论坛上发帖。

获取 Spring 新闻通讯

订阅 Spring 新闻通讯,保持联系

订阅

抢先一步

VMware 提供培训和认证,为您的进步加油助力。

了解更多

获取支持

Tanzu Spring 在一份简单的订阅中提供 OpenJDK™、Spring 和 Apache Tomcat® 的支持和二进制文件。

了解更多

即将举行的活动

查看 Spring 社区所有即将举行的活动。

查看全部