使用 SpringSource Application Platform 的供应存储库

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

SpringSource Application Platform 的主要优势之一是其按需供应依赖项的能力。这有两个好处:它确保平台内存占用尽可能小,并且允许应用程序在不将所有依赖项封装在单一部署单元(例如 WAR 文件)中的情况下进行部署。要利用这些功能,您需要了解平台的供应存储库,而这篇博文将提供这些信息。

供应存储库在哪里?它是如何工作的?

默认情况下,平台的供应存储库位于安装根目录下的 repository 目录中:供应存储库的目录结构 如您所见,有三个主要目录:bundlesinstalledlibrariesinstalled 用于平台内部使用,所以我们将重点关注 bundleslibraries 目录。每个目录包含多个子目录,用于分隔不同类型的依赖项。
  • ext 包含平台提供的外部依赖项,但它们本身并非平台的一部分。
  • subsystems 包含构成平台的所有子系统。
  • usr 最初为空,用于包含用户添加的依赖项,即您的应用程序依赖但平台尚未提供的任何内容。
平台在启动时搜索 repository 目录结构中的捆绑包和库。我将在本文后面讨论如何配置此搜索。当在存储库中找到捆绑包和库时,它们的符号名称、导出包等详细信息将被添加到存储库的内存索引中。扫描完成后,内存索引将被缓存到磁盘。在开发过程中,最小化平台的启动时间是我们的一个重点。这种缓存允许平台在启动时节省一些时间:除非检测到存储库内容已更改,否则它可以跳过扫描。

运行时供应

在纯粹的 OSGi 环境中,捆绑包的依赖项只能由已安装在环境中的其他捆绑包来满足。例如,安装和启动一个导入 org.apache.commons.dbcp 包的捆绑包,如果还没有任何导出该包的捆绑包被安装,将会失败。这对于用户来说可能非常麻烦,因为他们必须手动安装捆绑包的所有依赖项。幸运的是,SpringSource Application Platform 通过按需动态安装依赖项,大大改进了这一点。

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

  1. 一个导入了 org.apache.commons.dbcp 的捆绑包由平台安装到 Equinox 中。
  2. 平台向 Equinox 请求该捆绑包的未满足依赖项,并被告知对 org.apache.commons.dbcp 的导入无法满足。
  3. 平台在其供应存储库的索引中搜索导出 org.apache.commons.dbcp 的捆绑包。
  4. 平台将导出 org.apache.commons.dbcp 的捆绑包安装到 Equinox 中。
  5. 在满足了原始捆绑包的依赖项后,平台成功启动了该原始捆绑包。
我们希望这将极大地简化用户的生活:只要您的应用程序的依赖项对平台可用,您就可以简单地部署您的应用程序并开始使用!无需再耗费时间和精力手动安装应用程序的所有依赖项。这个过程的一个优点是依赖项仅在需要时安装。您可以将任意数量的捆绑包添加到供应存储库,而几乎不会对平台的内存占用产生影响。

如果平台无法从其存储库中满足某个依赖项,则会生成一条日志消息,详细说明无法满足的依赖项。有了这些信息,您可以使用 SpringSource Enterprise Bundle Repository 来获取所需内容。我们希望该存储库提供尽可能完整的捆绑包集:如果您需要某个依赖项而它不可用,请 告知我们

向供应存储库添加条目

所以,您已经下载了一两个依赖项,现在想将它们添加到平台。您只需将它们复制到存储库中的相应目录即可。例如,一个新的捆绑包通常会被添加到 repository/bundles/usr 目录,而一个新的库描述符通常会被添加到 repository/libraries/usr 目录。

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

跨安装共享供应存储库

平台搜索供应存储库中的条目的位置可以轻松配置以满足您的需求。例如,多个平台实例可以共享部分或全部供应存储库,这样您就不必费力地在平台安装之间维护重复的捆绑包集。

平台在创建其供应存储库时扫描的位置可以在 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}"
    ]
}

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

希望您能看到,共享部分或全部供应存储库在平台之间是一个微不足道的更改。例如,要让平台在文件系统的根目录下的一个名为 shared-bundles 的目录以及它自己的 subsystemsext 目录中进行搜索,您只需将以下 JSON(JavaScript 对象表示法)片段添加到 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 中的捆绑包。通过将所有搜索路径配置为指向共享位置,可以轻松地将此进一步发展,这样您就不必管理每个平台的供应存储库了。

下一步是什么?

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

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

我们非常希望听到您对我们正在开发的上述增强功能和平台本身的建议:请随时评论这篇博文、 提出 JIRA 或在我们的 论坛 上发帖。

获取 Spring 新闻通讯

通过 Spring 新闻通讯保持联系

订阅

领先一步

VMware 提供培训和认证,助您加速进步。

了解更多

获得支持

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

了解更多

即将举行的活动

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

查看所有