最近小編開發(fā)中使用SpringBoot,發(fā)現(xiàn)有許多基礎(chǔ)知識忘記了隘蝎,就邊復(fù)習(xí)基礎(chǔ)知識邊看一下源碼來增加記憶晒哄。小編還是菜鳥一個睁宰,寫這個也是方便記錄自己的理解肪获,如有錯誤,請各路大神指正柒傻。
package com.italkbb.sailing.broctrl;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
該類是程序的入口孝赫,根據(jù)自己的理解,寫了下該類的這幾句所代表的含義红符。
1青柄、Application是主類,運行這個主類main方法時预侯,程序會先初始化該主類致开。這時候的疑問(怎么初始化呢?什么叫初始化該類呢萎馅?做了什么呢双戳?)
當(dāng)程序主動使用這個Application類時,該類還未被加載到內(nèi)存中糜芳,則系統(tǒng)就會通過加載飒货、連接、初始化三個步驟來對該類初始化耍目。沒有意外的話膏斤,JVM將會完成這三個步驟徐绑,所以有時也把這三個步驟統(tǒng)稱為類加載或類初始化邪驮。
那第一步初始化Application類,而初始化的第一步又是類的加載和連接:會把該類的class文件讀入內(nèi)存傲茄,并為之創(chuàng)建一個java.lang.Class對象毅访,這一步其實被細(xì)稱為Application類的加載。也就是在下面方法里為啥可以使用Application.class來獲取這個類的Class對象盘榨,因為第一步類加載的時候喻粹,就生成啦。
這時候還沒有進(jìn)行Applicaiton類的初始化草巡,剛加載和連接完成守呜,隨后會檢查該類的直接父類有沒有被初始化,如果沒有山憨,會先初始化其直接父類查乒。而所有類的基類都是Object類,所以會去初始化基類郁竟。其實在過程中玛迄,類加載器也會去加載所有JDK中的jar包的class文件。
把所有父類都初始化(包括加載棚亩、連接蓖议、初始化)完成了虏杰,再初始化(主要是類變量初始化,加載和連接在第一步已完成)Application勒虾,而該類沒有類變量纺阔,所以就往下繼續(xù)走。
2修然、遇到SpringApplication.run()方法州弟,在遇到之前,還沒有加載低零、連接婆翔、初始化該類(為方便,以下統(tǒng)稱為初始化)掏婶。這時候為什么會初始化SpringApplication呢啃奴,因為一個類別初始化(加載、連接雄妥、初始化)有幾個時機(jī):
- 創(chuàng)建類的實例最蕾。為某個類創(chuàng)建實例的方式包括:使用new操作符來創(chuàng)建實例,通過反射來創(chuàng)建實例老厌,通過反序列化的方式來創(chuàng)建實例
- 調(diào)用某個類的類方法(靜態(tài)方法)
- 訪問某個類或接口的類變量瘟则,或為該類變量賦值。
- 使用反射方式來強(qiáng)制創(chuàng)建某個類或接口對應(yīng)的java.lang.Class對象枝秤。例如代碼:Class.forName("Person")醋拧,如果系統(tǒng)還未初始化Person類,則這行代碼將會導(dǎo)致該Person類被初始化淀弹,并返回Person類對應(yīng)的java.lang.Class對象丹壕。
- 初始化某個類的子類。當(dāng)初始化某個類的子類時薇溃,該子類的所有父類都會被初始化菌赖。
- 直接使用java.exe命令來運行某個主類時,程序會先初始化該主類沐序。
所以SpringApplication.run()是屬于第二種琉用,調(diào)用類的類方法,所以這時候會初始化SpringApplication類策幼。SpringApplication類中的這些變量肯定會被初始化啦邑时。
3、SpringApplication.run(Application.class, args)中只傳遞了兩個參數(shù)垄惧,一個就是Application的Class對象刁愿,該Application的Class對象是在該類加載的時候JVM為其生成的。為什么要傳遞它呢到逊,因為一旦獲取某個類所對應(yīng)的Class對象铣口,程序就可以調(diào)用Class對象的方法來獲得該類對象和該類的各種信息了滤钱。
SpringApplication.run(Application.class, args)傳遞Application的Class對象,以方便獲取Application類上的各種信息脑题,比如@SpringBootApplication注解件缸,獲取到該注解后,通過注解的注解解析器APT叔遂,為擁有該注解的類執(zhí)行一些自定義的操作他炊。這里又涉及注解的基礎(chǔ)知識。
這一個啟動類已艰,這是精簡痊末,超神,這就是SpringBoot的啟動類哩掺。往下的操作凿叠,還在繼續(xù)學(xué)習(xí)中卵迂。