本文介绍: 按文件结构约定依赖jar包必须放在 WEB-INF/lib 下,任何运行时必须但部署传统web容器时不必须的依赖放到 WEB-INF/libprovided 目录下,而应用程序classes 必须放在 BOOT-INF/classes 目录下。springboot 加载 嵌套jars 核心入口 org.springframework.boot.loader.jar.JarFilespringboot 程序使用 Maven PLugin插件编译时,可以生成执行jarwar 程序。

springboot 程序使用 Maven PLugin插件编译时,可以生成可执行jarwar 程序。其核心原理springbootloader 模块详细原理如下

java 本身不支持任何标准加载嵌套 jar方式,要解决问题很多使用 sharded jars 方式打包程序,将所有 jar 包从新打包一个独立的 “unionall.jar” 。但是 shared jars 方法使得很难判断应用程序代码归属、同时可能存在部分文件名冲突问题

springboot 使用一种不同方式实现嵌套 jar

springboot 加载 jar 文件结构如下

pmsuite-web-5.4.1-SNAPSHOT.jar
 |
 +-META-INF
 |  +-MANIFEST.MF
 +-org
 |  +-springframework
 |     +-boot
 |        +-loader
 |           +-<spring boot loader classes> # springboot 提供加载机制实现
 +-BOOT-INF
    +-classes
    |  +-cn
    |     +-pinming
    |        +-suite
    |            +-SuiteApplication.class
    |            +- ...
    |  +-static
    |  +-templates
    |  +-application.yml
    |  +-spring-config.xml
    |  +-....
    +-lib
       +-druid-1.1.23.jar
       +-dubbo-2.7.15.jar
       +-...

MANIFEST.MF 文件内容

Manifest-Version: 1.0
Implementation-Title: pmsuite-web
Implementation-Version: 5.4.1-SNAPSHOT
Built-By: Administrator
Specification-Title: pmsuite-web
Implementation-Vendor-Id: cn.pinming
Spring-Boot-Version: 2.1.3.RELEASE
Main-Class: org.springframework.boot.loader.JarLauncher
Start-Class: cn.pinming.pmsuite.SuiteApplication
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Created-By: Apache Maven 3.8.1
Build-Jdk: 1.8.0_131
Specification-Version: 5.4
Implementation-URL: https://projects.spring.io/spring-boot/#/spring-bo
 ot-starter-parent/pmsuite-boot-project/pmsuite/pmsuite-basic-parent/p
 msuite-web

按文件结构约定依赖jar包必须放在 WEB-INF/lib 下,任何运行时必须但部署传统web容器时不必须的依赖放到 WEB-INF/libprovided 目录下,而应用程序classes 必须放在 BOOT-INF/classes 目录下。

Spring Boot Loader-compatible jar and war 文件可以 在 BOOT-INF/ 目录存放扩展索引文件。 一个 classpath.idx 文件可以为 jar 和 war 文件提供扩展 jars 依赖,而 layers.idx 仅仅为 jar 可执行文件服务

索引文件使用 YAML 兼容语法。索引文件案例:

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

索引文件如下:

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

springboot 加载 嵌套jars 核心入口 org.springframework.boot.loader.jar.JarFile 。该程序从一个标准 jar 文件 或 嵌套子 jar 文件中加载数据

springboot 使用 org.springframework.boot.loader.Launcher 作为 java 程序加载主程序。该程序是一个 springboot 启动程序。

启动程序包括三个子加载程序 JarLauncher, WarLauncher, and PropertiesLauncher。

PropertiesLauncher 加载一些扩展特性比如系统配置环境变量mainfest 入口、或加载配置)。详细配置清单如下:

键值 用途
loader.path 使用逗号分割classpath,如 ${home}/app/lib。 类似 javac命令行的 –classpath 参数
loader.home loader.pathloader.propertis 中如果使用相对目录时的跟目录。
loader.args 程序启动参数多个参数使用空格分割
loader.main 程序启动mainclass,如 SuiteApplication.class
loader.config.name loader配置名称
loader.config.location loader配置路径默认 classpath:loader.propertis
loader.system 判断配置是否加载到系统配置中,默认 false

loader.properties: 先从loader.home,如果找不到查询classpath跟目录,最后查询 classpath:/BOOT-INF/classes。 使用最先找到配置
loader.home:只有在loader.config.location为配置时,才会从该目录加载扩展配置(覆盖默认配置)。
loader.path可以包含目录(包含 jar 或 zip文件)、JAR归档文件路径内容包括诸如:dependencies.jar!/lib)、正则表达式
loader.path默认值为 BOOT-INF/lib (表示从嵌套 jar归档文件中加载),该情况下不需要加载额外配置信息
配置信息搜索顺序environment variables, system properties, loader.properties, the exploded archive manifest, and the archive manifest.

使用 loader.path 方式启动 springboot程序

java -jar -Djava.ext.dirs=./libs

如果在libs内 ,命令-Djava.ext.dirs=参数为./ ,如果生成jar与libs同级那么改为./libs 意思就是告诉jar 我的依赖jar包相对于我要执行的jar包的位置在哪里

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注