SpringBoot打包的jar分析,java -jar是在哪里开始启动项目的?
一般情况下来说,在pom文件中没有指定layout的默认值为:JAR
<?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">
<!-- 省略.... -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<!--<layout>ZIP</layout>-->
</configuration>
</plugin>
</plugins>
</build>
</project>
官方定义有5种见:org.springframework.boot.maven.AbstractPackagerMojo.LayoutType
public enum LayoutType {
JAR(new Jar()),
WAR(new War()),
ZIP(new Expanded()),
DIR(new Expanded()),
NONE(new None());
// 省略...
}
名称 | 启动类 |
---|---|
JAR | org.springframework.boot.loader.JarLauncher |
WAR | org.springframework.boot.loader.WarLauncher |
ZIP | org.springframework.boot.loader.PropertiesLauncher |
DIR | org.springframework.boot.loader.PropertiesLauncher |
NONE | 项目本身入口类 |
把jar解压有3个文件夹:
BOOT-INF:这个是我们自己写的编译后的class文件
META-INF:相当于描述文件,里面包含了项目的pom文件、项目版本信息以及MANIFEST.MF描述文件
org:jar包运行的入口程序 => spring-boot-load项目的编译后的class文件
MANIFEST.MF
键 | 值(以下值为举例) | 描述 |
---|---|---|
Manifest-Version | 1.0 | 版本 |
Spring-Boot-Classpath-Index | BOOT-INF/classpath.idx | 内容是项目中用到依赖,一般是BOOT-INF/lib下jar的相对路径 |
Implementation-Title | demo | 项目名称,对应pom文件的name标签 |
Implementation-Version | 1.0.0 | 项目版本,对应pom文件的version标签 |
Spring-Boot-Layers-Index | BOOT-INF/layers.idx | 内容也是一些项目相关的路径信息 |
Start-Class | com.example.demo.DemoApplication | 项目启动类路径 |
Spring-Boot-Classes | BOOT-INF/classes/ | 项目编译后的class文件路径 |
Spring-Boot-Lib | BOOT-INF/lib/ | 项目所引用的依赖包的路径 |
Build-Jdk-Spec | 1.8 | jdk版本 |
Spring-Boot-Version | 2.3.10.RELEASE | springboot版本 |
Created-By | Maven Jar Plugin 3.2.0 | maven jar plugin信息 |
Main-Class | org.springframework.boot.loader.JarLauncher | java -jar启动的入口类 |
以下我们可以分析一下,不同layout的jar包的MANIFEST.MF是怎么描述的:
1. JAR(默认)
Manifest-Version: 1.0
Spring-Boot-Classpath-Index: BOOT-INF/classpath.idx
Implementation-Title: demo
Implementation-Version: 1.0.0
Start-Class: com.example.demo.DemoApplication
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Build-Jdk-Spec: 1.8
Spring-Boot-Version: 2.3.10.RELEASE
Created-By: Maven Jar Plugin 3.2.0
Main-Class: org.springframework.boot.loader.JarLauncher
2. ZIP(或者: DIR)
Manifest-Version: 1.0
Spring-Boot-Classpath-Index: BOOT-INF/classpath.idx
Implementation-Title: demo
Implementation-Version: 1.0.0
Spring-Boot-Layers-Index: BOOT-INF/layers.idx
Start-Class: com.example.demo.DemoApplication
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Build-Jdk-Spec: 1.8
Spring-Boot-Version: 2.5.3
Created-By: Maven Jar Plugin 3.2.0
Main-Class: org.springframework.boot.loader.PropertiesLauncher
3. NONE
Manifest-Version: 1.0
Spring-Boot-Classpath-Index: BOOT-INF/classpath.idx
Implementation-Title: demo
Implementation-Version: 1.0.0
Spring-Boot-Layers-Index: BOOT-INF/layers.idx
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Build-Jdk-Spec: 1.8
Spring-Boot-Version: 2.5.3
Created-By: Maven Jar Plugin 3.2.0
Main-Class: com.example.demo.DemoApplication
注:这种方式打包出来的jar,是不会包含org文件夹,也就是没有spring-boot-load项目的编译后的class文件
4. WAR
Manifest-Version: 1.0
Spring-Boot-Classpath-Index: WEB-INF/classpath.idx
Implementation-Title: demo
Implementation-Version: 1.0.1
Spring-Boot-Layers-Index: WEB-INF/layers.idx
Start-Class: com.example.demo.DemoApplication
Spring-Boot-Classes: WEB-INF/classes/
Spring-Boot-Lib: WEB-INF/lib/
Build-Jdk-Spec: 1.8
Spring-Boot-Version: 2.5.3
Created-By: Maven WAR Plugin 3.3.1
Main-Class: org.springframework.boot.loader.WarLauncher
总结
对接上述4个描述文件,
JAR、ZIP、DIR:这三个文件后缀为:.jar,启动类分别是:JarLanucher、PropertiesLauncher
WAR:文件后缀为:.war,启动类为:WarLanucher。并且一些文件目录名字以WEB开头
NONE:文件后缀为:.jar,启动类为项目本身入口
java -jar 方式运行项目一般都是从Main-Class配置的类开始的,通过spring-boot-load项目去加载真实项目的class文件、配置文件等,根据Start-Class配置的类去启动真实的项目。