SpringBoot學習系列-jar包啟動原理


打包生成兩個jar包
ssmdemo-plus.jar 引入了相關第三方依賴。
ssmdemo-plus.jar.original 僅包含應用編譯后的本地資源
 
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 {
    JarFile.registerUrlProtocolHandler();
    ClassLoader classLoader = this.createClassLoader(this.getClassPathArchives());
    this.launch(args, this.getMainClass(), classLoader);
}

JarFile.registerUrlProtocolHandler(); 

這個方法作用:

利用java url協議實現擴展原理,自定義jar協議
將org.springframework.boot.loader包 追加到java系統 屬性java.protocol.handler.pkgs中,實現自定義jar協議

參考鏈接:java 自定義通訊協議 [https://blog.csdn.net/d_x_program/article/details/75038200]
java會在java.protocol.handler.pkgs系統屬性指定的包中查找與協議同名的子包和名為Handler的類,
即負責處理當前協議的URLStreamHandler實現類必須在 <包名>.<協議名定義的包> 中,並且類名稱必須為Handler
例如:
org.springframework.boot.loader.jar.Handler這個類 將用於處理jar協議

這個jar協議實現作用:
參考鏈接:SpringBoot FatJar啟動原理 [https://www.cnblogs.com/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 = this.createClassLoader(this.getClassPathArchives());
創建類加載器,得到可以加載嵌套式的jar文件的類加載器
 
然后
調用this.launch(args, this.getMainClass(), classLoader);方法,
讀取Manifest的Start-Class屬性利用反射執行main方法完成應用程序的啟動
start-class屬性其實就是我們項目里面的Application程序

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM