嵌套 JAR
Java 并未提供任何标准方式来加载嵌套的 JAR 文件(即,自身被包含在另一个 JAR 文件中的 JAR 文件)。 如果需要分发一个自包含的应用程序,并且该应用程序需能够直接从命令行运行而无需解压,则这可能成为一个问题。
为了解决这一问题,许多开发人员会使用“重命名(shaded)”的 JAR 包。 重命名 JAR 包会将所有 JAR 包中的全部类打包进一个单独的“超级(uber)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"
Spring Boot 仅在使用 java -jar 执行 JAR 或 WAR 文件时才使用类路径索引文件。
当从 IDE 运行应用程序,或使用 Maven 的 spring-boot:run 或 Gradle 的 bootRun 时,不会使用该索引文件。 |
| 启用可重现构建时,类路径索引文件中的条目将按字母顺序排序。 |
层索引
层索引文件可置于 BOOT-INF/layers.idx 中。
该文件提供了一份层列表,以及各 JAR 文件中应包含于对应层的组成部分。
层将按其应添加至 Docker/OCI 镜像的顺序进行写入。
层名称以带引号的字符串形式书写,并以短横线加空格("-·")为前缀,以冒号(":")为后缀。
层内容为文件或目录名称,以带引号的字符串形式书写,并以两个空格加短横线加空格("··-·")为前缀。
目录名称以 / 结尾,而文件名称则不以此结尾。
当使用目录名称时,表示该目录内的所有文件均属于同一层。
典型的层索引示例如下:
- "dependencies":
- "BOOT-INF/lib/dependency1.jar"
- "BOOT-INF/lib/dependency2.jar"
- "application":
- "BOOT-INF/classes/"
- "META-INF/"