嵌套 JARs

Java 没有提供加载嵌套 jar 文件(即包含在另一个 jar 文件中的 jar 文件)的标准方法。如果你需要分发一个可以从命令行运行而无需解压的自包含应用程序,这可能会带来问题。

为了解决这个问题,许多开发者使用“shaded” jar。Shaded jar 将所有 jar 中的所有类打包到一个“uber jar”中。Shaded jar 的问题在于很难看出你的应用中实际包含哪些库。如果在多个 jar 中使用了相同的文件名(但内容不同),也可能出现问题。Spring Boot 采取了不同的方法,允许你直接嵌套 jar。

可执行 Jar 文件结构

Spring Boot Loader 兼容的 jar 文件应该按照以下方式组织结构

example.jar
 |
 +-META-INF
 |  +-MANIFEST.MF
 +-org
 |  +-springframework
 |     +-boot
 |        +-loader
 |           +-<spring boot loader classes>
 +-BOOT-INF
    +-classes
    |  +-mycompany
    |     +-project
    |        +-YourClasses.class
    +-lib
       +-dependency1.jar
       +-dependency2.jar

应用程序类应放在嵌套的 BOOT-INF/classes 目录中。依赖项应放在嵌套的 BOOT-INF/lib 目录中。

可执行 War 文件结构

Spring Boot Loader 兼容的 war 文件应按照以下方式组织结构

example.war
 |
 +-META-INF
 |  +-MANIFEST.MF
 +-org
 |  +-springframework
 |     +-boot
 |        +-loader
 |           +-<spring boot loader classes>
 +-WEB-INF
    +-classes
    |  +-com
    |     +-mycompany
    |        +-project
    |           +-YourClasses.class
    +-lib
    |  +-dependency1.jar
    |  +-dependency2.jar
    +-lib-provided
       +-servlet-api.jar
       +-dependency3.jar

依赖项应放在嵌套的 WEB-INF/lib 目录中。在嵌入式运行时需要但在部署到传统 Web 容器时不需要的任何依赖项,应放在 WEB-INF/lib-provided 目录中。

索引文件

Spring Boot Loader 兼容的 jar 和 war 归档文件可以在 BOOT-INF/ 目录下包含额外的索引文件。jar 和 war 文件都可以提供 classpath.idx 文件,它提供了 jar 应添加到 classpath 的顺序。layers.idx 文件只能用于 jar,它允许将 jar 拆分为逻辑层,以便创建 Docker/OCI 镜像。

索引文件遵循 YAML 兼容的语法,以便第三方工具可以轻松解析它们。然而,这些文件在内部 不会 被解析为 YAML,并且必须严格按照下面描述的格式编写才能使用。

Classpath 索引

Classpath 索引文件可以在 BOOT-INF/classpath.idx 中提供。通常,它由 Spring Boot 的 Maven 和 Gradle 构建插件自动生成。它提供了一个 jar 文件名(包括目录)列表,按它们应添加到 classpath 的顺序排列。当由构建插件生成时,此 classpath 顺序与构建系统用于运行和测试应用程序的顺序一致。每行必须以破折号空格("-·")开头,名称必须用双引号括起来。

例如,给定以下 jar

example.jar
 |
 +-META-INF
 |  +-...
 +-BOOT-INF
    +-classes
    |  +...
    +-lib
       +-dependency1.jar
       +-dependency2.jar

索引文件将如下所示

- "BOOT-INF/lib/dependency2.jar"
- "BOOT-INF/lib/dependency1.jar"
Spring Boot 仅在使用 java -jar 执行 jar 或 war 文件时使用 classpath 索引文件。从 IDE 运行应用程序时或使用 Maven 的 spring-boot:run 或 Gradle 的 bootRun 时不使用它。
启用可重现构建时,classpath 索引文件中的条目按字母顺序排序。

层索引

层索引文件可以在 BOOT-INF/layers.idx 中提供。它提供了一个层列表以及每个层应包含的 jar 部分。层按照它们应添加到 Docker/OCI 镜像的顺序编写。层名称写成带引号的字符串,前缀为破折号空格("-·"),后缀为冒号(":")。层内容是文件或目录名,写成带引号的字符串,前缀为两个空格加破折号空格("··-·")。目录名以 / 结尾,文件名则不以 / 结尾。当使用目录名时,意味着该目录内的所有文件都在同一层。

层索引的典型示例如下

- "dependencies":
  - "BOOT-INF/lib/dependency1.jar"
  - "BOOT-INF/lib/dependency2.jar"
- "application":
  - "BOOT-INF/classes/"
  - "META-INF/"