1. 程式人生 > >springboot源碼學習筆記之進入之前發生了啥

springboot源碼學習筆記之進入之前發生了啥

依賴包 cio margin padding 項目打包 定義類 定義 tro 托管

人稱: 露哥
QQ: 408365330
N01.編程就是驗證學習的最好方式
N02.為了掙錢所以編程,為了掙大錢所以寫好代碼,為了寫好代碼所以學習
N03.好好學習天天編程

springboot源碼學習筆記之進入之前發生了啥

雖然用springboot也有一段時間,但是之前也沒怎麽關註過springboot項目打包過程中發生了什麽,啟動過程細節是什麽!
直到最近在搞公司的私有化大平臺時需要了解更多的本質上的東西才細細品味了一下springboot的源碼,從起源開始……

springboot 程序長啥樣(身材和臉蛋)?

@SpringBootApplication
@EnableAutoConfiguration
public class EgojitApplication {
    public static void main(String[] args) {
        SpringApplication.run(EgojitApplication.class, args);
    }
}

我第一眼看到特別親切,這就是一個main程序啊;然後再看一眼,好像比普通的main上面多了兩個註解,總以為兩眼就了解她,和普通的main也沒什麽不同麽啊,其實只是了解了身材和臉蛋;需要三回眸免得錯過什麽精彩內容;然後我使用 spring-boot-maven-plugin

進行打包;生成一個jar包;既然要深入了解她的“品質”啊,那就得由內而外;unzip 這個美麗的jar吧;

springboot的jar包內在(品質)

名詞說明

我們這裏把由 spring-boot-maven-plugin maven插件打包的jar包稱為“胖jar”或者“聚合jar”(不僅僅只有這一種打包胖jar的方式,我們約定胖jar就是spring-boot-maven-plugin插件打包的jar包,我喜歡約定),把maven-jar-plugin 默認打包出來的jar包稱為“瘦jar”或者“散jar”

  • 胖jar/聚合jar
    整個項目會打包成一個jar包,所有的依賴jar包被打進一個jar包

  • 瘦jar/散jar
    整個項目jar包是散的,依賴的包和項目主class或者jar是平行的

N01 有內涵

技術分享圖片
unzip後發現這個和普通的main程序jar包完全不同啊,包含BOOT-INF,META-INF,org三個目錄;然後可以看見BOOT-INF/classes才是真正的classpath,而傳統的jar包直接解壓後就是classpath

N02 有特色

技術分享圖片
META-INF目錄中我重點關註MANIFEST.INF文件,我看到了我不敢相信的一幕,她和普通main區別大大的,她可不是表面上看到的那樣,入口main在JarLauncher中(記住它後面我們分析spring-boot-loader源碼從它入手);所以我推翻我之前的認知springboot的xxxApplicaion中的main不是普通的main。它只是一個被xxxApplicion調用的普通方法而已;和普通的MANIFEST.INF不同它還有一個Start-Class,不要懷疑這個就是我們寫的xxxApplicaion; Spring-Boot-Classes指出了springboot的特殊class目錄;Spring-Boot-Lib配置第三方依賴包目錄

N03 超仙

技術分享圖片

org目錄有點神奇,出現了超自然現象啊,我的項目絕對沒有org.springframework.boot包啊。它從哪裏來的?我懷疑人生的打開項目依賴找了一遍,我確定它是超自然現象,好仙,不是我等凡人容易理解的;我想到既然我沒幹什麽,那就絕對是打包幹的,誰打包?????
spring-boot-maven-plugin 對!就是它,被我逮到了;它把項目打包成我們看到的目錄結構,同時把spring-boot-loader jar包中的class拷貝到項目中了;

spring-boot-loader 分析

以下是JarLauncher執行流程分析

技術分享圖片

通過源碼分析流程可以知道spring-boot-load模塊通過自定義jar包結構自定義類加載器優雅的實現了嵌套jar資源的加載,通過打包時候重新設置啟動類和組織jar結構,通過運行時設置自定義加載器來實現嵌套jar資源加載;
知道這些我們可以實現自己的JarLauncher實現Archive動態指定實現插件化;既然spring-boot-loader能指定lib以及class目錄,那麽我們也可以實現自己的JarLauncher合並更多的lib目錄,實現外部擴展lib,再結合spring boot中的spring.factries的原理掃描註入代碼;公司的私有化平臺中的應用托管就是我在研究spring-boot-loader這種原理結合spring boot中的spring.factries的機制基礎上實現的;改造了原來基於java的jagent方式。這種方案解決了很多問題;其中第三方springboot應用日誌采集,性能監控,健康檢查等等都可以基於這個機制去實現(了解這個原理多麽重要);更多的就涉密了……。哈哈……

springboot源碼學習筆記之進入之前發生了啥