SpringBoot学习系列-jar包启动原理打包⽣成两个jar包
ssmdemo-plus.jar 引⼊了相关第三⽅依赖。
maven打包本地jar包iginal 仅包含应⽤编译后的本地资源
jar包的⽬录结构
|—— BOOT-INF
|—— classes  存放的是应⽤编译后的class⽂件
|—— lib    存放的是应⽤依赖的第三⽅jar包⽂件
|——META-INF    存放应⽤打包信息maven坐标、pom⽂件和MANIFEST.MF
|—— MANIFEST.MF
|—— maven
|—— org  ⽬录存放SpringBoot相关class⽂件
|—— springframework
使⽤java -jar命令执⾏ spring Boot 应⽤的可执⾏jar⽂件
会读取META-INF/MANIFEST.MF⽂件的Main-Class属性值,该值表⽰应⽤程序执⾏⼊⼝类MANIFEST.MF⽂件内容
Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Built-By: NB-20200504-3
Start-Class: com.zwh.Application
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Spring-Boot-Version: 2.2.3.RELEASE
Created-By: Apache Maven 3.6.1
Build-Jdk: 1.8.0_231
Main-Class: org.springframework.boot.loader.JarLauncher
会执⾏org.springframework.boot.loader包下的JarLauncher的main⽅法
这⾥会做操作
JarLauncher.java
public static void main(String[] args) throws Exception {
(new JarLauncher()).launch(args);
}
Launcher.java
protected void launch(String[] args) throws Exception {
ClassLoader classLoader = ClassPathArchives());
this.launch(args, MainClass(), classLoader);
}
这个⽅法作⽤:
利⽤java url协议实现扩展原理,⾃定义jar协议
将org.springframework.boot.loader包追加到java系统属性java.protocol.handler.pkgs中,实现⾃定义jar协议
参考链接:java ⾃定义通讯协议 [blog.csdn/d_x_program/article/details/75038200]
java会在java.protocol.handler.pkgs系统属性指定的包中查与协议同名的⼦包和名为Handler的类,
即负责处理当前协议的URLStreamHandler实现类必须在 <;包名>.<;协议名定义的包> 中,并且类名称必须为Handler
例如:
org.springframework.boot.loader.jar.Handler这个类将⽤于处理jar协议
这个jar协议实现作⽤:
参考链接:SpringBoot FatJar启动原理 [wwwblogs/jfire/p/11973093.html]
springBoot在打包时候会将第三⽅依赖jar包打进最终的Jar,变成⼀个可运⾏的FatJar。
默认情况下,JDK提供的ClassLoader只能识别jar中的class⽂件以及加载classpath下的其他jar包中的class⽂件。
对于jar包中的jar包是⽆法加载的
所以spring boot ⾃⼰定义了⼀套URLStreamHandler实现类和JarURLConnection实现类,⽤来加载jar包中的jar包的class类⽂件
下⼀步
ClassLoader classLoader = ClassPathArchives());
创建类加载器,得到可以加载嵌套式的jar⽂件的类加载器
然后
调⽤this.launch(args, MainClass(), classLoader);⽅法,
读取Manifest的Start-Class属性利⽤反射执⾏main⽅法完成应⽤程序的启动
start-class属性其实就是我们项⽬⾥⾯的Application程序