文章目录
- Fat Jar
- 瘦身
- pom修改
- copy lib
- 启动 -Dloader.path
- 验证
- 源码分析
- 前置阅读
- spring-boot-loader 依赖
- 类继承关系
- PropertiesLauncher属性配置
- 附 pom.xml
Fat Jar
【pom.xml】
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.16</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.artisan</groupId><artifactId>thinBootJar</artifactId><version>0.0.1-SNAPSHOT</version><name>thinBootJar</name><description>thinBootJar</description><properties><java.version>8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><image><builder>paketobuildpacks/builder-jammy-base:latest</builder></image></configuration></plugin></plugins></build></project>
打包后观察目录
重点关注下Main-Class
瘦身
pom修改
<build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><!-- 用来配置可执行jar包中Main-Class的类型,这里一定要设置为 ZIP,使打的jar包中的Main-Class为PropertiesLauncher--><layout>ZIP</layout><includes><!-- 不打依赖包 --><include><!-- nothing 代表不存在的依赖包,意思就是什么依赖包都不引入--><groupId>nothing</groupId><artifactId>nothing</artifactId></include><!-- <include>--><!-- common是引入的公共服务模块 --><!-- <groupId>com.xxx.xx.rpc</groupId>--><!-- <artifactId>common</artifactId>--><!-- </include>--></includes></configuration></plugin></plugins></build>
JAR,即通常的可执行jar
Main-Class: org.springframework.boot.loader.JarLauncher
WAR,即通常的可执行war,需要的servlet容器依赖位于WEB-INF/lib-provided
Main-Class: org.springframework.boot.loader.warLauncher
ZIP,即DIR,类似于JAR
Main-Class: org.springframework.boot.loader.PropertiesLauncher
MODULE,将所有的依赖库打包(scope为provided的除外),但是不打包Spring Boot的任何Launcher
NONE,将所有的依赖库打包,但是不打包Spring Boot的任何Launcher
打包后观察下 jar包 的大小 和 里面的内容
重点关注下Main-Class
copy lib
<!-- 将依赖的jar包copy到lib目录下 --><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-dependency-plugin</artifactId><executions><execution><id>copy</id><phase>package</phase><goals><goal>copy-dependencies</goal></goals><configuration><!-- 指定依赖的路径 --><outputDirectory>${project.build.directory}/lib</outputDirectory></configuration></execution></executions></plugin>
打包后观察下
启动 -Dloader.path
为了让名字好看一点
java -Dloader.path=./lib -jar artisan-test-thin-boot-jar.jar
验证
通过启动参数loader.path
配置外置依赖包的加载路径。 项目成功启动,说明我们配置的外包依赖包加载生效了
源码分析
前置阅读
SpringBoot - 探究Spring Boot应用是如何通过java -jar 启动的
SpringBoot(二) 启动分析JarLauncher
spring-boot-loader 依赖
为了方便查看源码,我们引入如下依赖
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-loader --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-loader</artifactId></dependency>
类继承关系
org.springframework.boot.loader.Launcher
类是特殊的引导程序类,用作可执行jar的主要入口点。它是jar文件中的实际Main-Class,用于设置适当的URLClassLoader并最终调用main()方法
-
有三个启动器子类(
JarLauncher
,WarLauncher
和PropertiesLauncher
)。它们的目的是从目录中的嵌套jar文件或war文件(而不是在类路径中显式的文件)加载资源(.class文件等)。 -
对于
JarLauncher
和WarLauncher
,嵌套路径是固定的。JarLauncher
位于BOOT-INF / lib /
中,而WarLauncher
位于WEB-INF / lib /
和WEB-INF / lib-provided /
中。如果需要,可以在这些位置添加额外的罐子。 -
默认情况下,
PropertiesLauncher
在应用程序存档中的BOOT-INF / lib /
中查找。可以通过在loader.properties
(这是目录,归档文件或归档文件中的目录的逗号分隔列表)中设置一个称为LOADER_PATH
或loader.path
的环境变量来添加其他位置
概括一下: 启动器Launcher是为了项目启动加载依赖资源的,共有3个启动器 JarLauncher,WarLauncher和PropertiesLauncher ,
- JarLauncher和WarLauncher加载资源的路径是固定的,
- PropertiesLauncher可以通过环境变量loader.path来指定加载资源的位置
layout属性值说明:
- JAR,即通常的可执行jar
Main-Class:org.springframework.boot.loader.JarLauncher
- WAR,即通常的可执行war,需要的servlet容器依赖位于
Main-Class:org.springframework.boot.loader.warLauncher
- ZIP,即DIR,类似于JAR
Main-Class:org.springframework.boot.loader.PropertiesLauncher
PropertiesLauncher属性配置
- loader.path: 用于定义lib包加载路径。
- loader.home: 解析loader.path中相对路径的基础路径,通常是类路径位置。
- loader.args: 设置main方法的默认参数,以空格分隔。
- loader.main: 指定要启动的主类的名称,例如com.xxx.Application。
- loader.config.name: 指定属性文件的路径,例如classpath:loader.properties。
- loader.system: 一个布尔值标志,指示是否将所有属性添加到系统属性,默认为false。
附 pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.16</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.artisan</groupId><artifactId>thinBootJar</artifactId><version>0.0.1-SNAPSHOT</version><name>thinBootJar</name><description>thinBootJar</description><properties><java.version>8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><build><finalName>artisan-test-thin-boot-jar</finalName><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><!-- 用来配置可执行jar包中Main-Class的类型,这里一定要设置为 ZIP,使打的jar包中的Main-Class为PropertiesLauncher--><layout>ZIP</layout><includes><!-- 不打依赖包 --><include><!-- nothing 代表不存在的依赖包,意思就是什么依赖包都不引入--><groupId>nothing</groupId><artifactId>nothing</artifactId></include><!-- <include>--><!-- common是引入的公共服务模块 --><!-- <groupId>com.xxx.xx.rpc</groupId>--><!-- <artifactId>common</artifactId>--><!-- </include>--></includes></configuration></plugin><!-- 将依赖的jar包copy到lib目录下 --><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-dependency-plugin</artifactId><executions><execution><id>copy</id><phase>package</phase><goals><goal>copy-dependencies</goal></goals><configuration><!-- 指定依赖的路径 --><outputDirectory>${project.build.directory}/lib</outputDirectory></configuration></execution></executions></plugin></plugins></build></project>