嵌套 JAR

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

为了解决这个问题,许多开发者使用“阴影”jar。阴影jar将所有jar中的所有类打包到一个单独的“超级jar”中。阴影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/目录下包含额外的索引文件。classpath.idx文件可以同时用于jar和war,它提供jar添加到类路径的顺序。layers.idx文件只能用于jar,它允许将jar拆分为逻辑层以创建Docker/OCI镜像。

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

类路径索引

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

例如,给定以下jar

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

索引文件将如下所示

- "BOOT-INF/lib/dependency2.jar"
- "BOOT-INF/lib/dependency1.jar"

层索引

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

层索引的典型示例如下

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