Spring Boot 如何加载非 Classpath 类路径下的外部 JAR 和配置文件


Launcher(启动器)

org.springframework.boot.loader.Launcher 类是一个特殊的引导类,是 Spring Boot 可执行 jar 的主要入口点,它是 Spring Boot jar 文件中的实际 Main-Class,用于设置适当的 URLClassLoader 并最终调用 Spring Boot 项目中定义的 main() 方法。

Launcher有三个子类(JarLauncher、WarLauncher 和 PropertiesLauncher),与那些直接在类路径上的文件不同,它们的目的是从目录中加载嵌套 jar 或 war 文件中的资源(例如 .class 文件等)。对于 JarLauncher 和 WarLauncher,加载路径是固定的,JarLauncher 在 BOOT-INF/lib/中加载,而 WarLauncher 在 WEB-INF/lib/WEB-INF/lib-provided/ 中加载。我们可以在这些路径下添加我们想要加载的其它 jar,例如下例中的 a.jar:

默认情况下,PropertiesLauncher 在 BOOT-INF/lib/ 中加载,我们可以通过设置 loader.properties 中的 loader.pathLOADER_PATH 环境变量来增加其它的加载位置。

PropertiesLauncher

PropertiesLauncher 有一些可以通过外部属性(系统属性、环境变量、清单条目或 loader.properties)启用的特定功能。

  • loader.path:配置逗号分隔的 Classpath 类路径,例如 lib,${HOME}/app/lib,前面的路径优先,类似于 javac 命令中的 -classpath。
  • loader.home:用于解析 loader.path 配置的相对路径,默认是 ${user.dir}。

我们可以通过如下配置来选择使用 PropertiesLauncher:

1
2
3
4
5
6
7
8
9
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>${start.class}</mainClass>
<layout>ZIP</layout>
</configuration>
</plugin>

默认是根据 <packing> 打包类型( jar 或 war)来确定 Launcher 类型,这里是通过 ZIP 配置来选择使用哪个 Launcher:

  • JAR
  • WAR
  • ZIP:使用 PropertiesLauncher
  • NONE: 不捆绑引导加载程序

打包成功后,我们通过 java -jar -Dloader.path=conf,lib <jarName>.jar 命令来启动程序,则 ${user.dir}/lib 中的外部 jar,${user.dir}/conf 中的外部配置均会被加载。