Spring Boot打包底层细节
jar的目录内容
在OSX下使用 unzip xxx.jar -d ./newdir 把解压缩文件放到新建目录
Spring Boot打成Jar包的目录结构如图所示:
BOOT-INF: 项目工程文件和依赖的所有Jar包
META-INF: 清单文件,描述可执行jar包的一些信息
org: Spring Boot 提供的class,在spring-boot-maven-plugin插件当中,在打包时动态提取的
可以增加依赖引入:spring-boot-loader,对研究SpringBoot打包机制源码有帮助,打包后的目录结构是在JarLauncher定义的
Spring Boot如何打包和执行
关键包:spring-boot-loader
当我们运行java -jar xxx.jar
时,spring boot到底是怎么帮我们启动程序的
从Main-Class: org.springframework.boot.loader.JarLauncher
入手找到JarLauncher
类,从main
方法开始执行
该类的父类为ExecutableArchiveLauncher
,该父类还有一个实现WarLauncher
用于打War
包
JarLauncher的继承结构如下:
被指定为
Main-Class
类的目录结构一定是放在jar文件中的顶层目录
- 一般的jar标准是不允许jar文件中还存在jar文件的
通常maven的做法是使用shade插件
把被依赖的jar文件的内容拷贝到被打包的jar文件中,但是存在缺陷
- 目录结构不清晰
- 相同目录同名的文件可能有被覆盖的风险
Spring Boot通过嵌套的jar,通过应用类加载器加载spring-boot-loader的类(文件夹org
),然后自定义一个类加载器(LaunchedURLClassLoader
,继承于URLClassLoader)加载嵌套的依赖jar(FatJar
)和自己应用的class
Archive对象代表的是classes文件或者lib下的jar