91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

SpringBoot應用的啟動入口怎么封裝

發布時間:2022-05-23 11:25:14 來源:億速云 閱讀:135 作者:iii 欄目:開發技術

這篇文章主要介紹了SpringBoot應用的啟動入口怎么封裝的相關知識,內容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇SpringBoot應用的啟動入口怎么封裝文章都會有所收獲,下面我們一起來看看吧。

SpringBoot應用的啟動入口怎么封裝

Springboot可以說是Java程序員必備技能了,大家都知道Springboot最終可以通過maven打成jar包,然后直接使用java -jar命令運行一個Web工程(或其它)。這樣就避免了原先基于tomcat的web工程的復雜操作。Springboot能夠使Web服務的部署簡單到如此程度是因為其內置了Jetty(或Tomcat)服務器,并且在容器啟動過程中start該服務器,成功運行Web服務。

相信各位Springbooter一定不會陌生下面的代碼,無論是初學Springboot的新同學,或是開始研究Springboot源碼的新司機,這段代碼幾乎是我們的落腳點。我們如此熟悉它,以至于認為它就是Springboot這個魔法樂園的起點。但真的是這樣嗎?

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

我們都知道,一個Java工程打包過后,這個jar包的入口描述被寫在了/META-INF/MANIFEST.MF文件下,下面讓我們來看看這個文件內容:

 Manifest-Version: 1.0
 Archiver-Version: Plexus Archiver
 Built-By: MrXu
 Start-Class: com.vivo.internet.nex.repeater.console.RepeaterConsoleApplication
 Spring-Boot-Classes: BOOT-INF/classes/
 Spring-Boot-Lib: BOOT-INF/lib/
 Spring-Boot-Version: 1.5.19.RELEASE
 Created-By: Apache Maven 3.8.1
 Build-Jdk: 1.8.0_281
 Main-Class: org.springframework.boot.loader.JarLauncher

文件入口的描述為Main-Class對應的value,即org.springframework.boot.loader.JarLauncher。那么,接下來我們需要看下這個類究竟做了什么?

 // JarLauncher.java
 public class JarLauncher extends ExecutableArchiveLauncher {
     static final String BOOT_INF_CLASSES = "BOOT-INF/classes/";
     static final String BOOT_INF_LIB = "BOOT-INF/lib/";
     public JarLauncher() {
     }
     // ...省略無關代碼
     public static void main(String[] args) throws Exception {
         (new JarLauncher()).launch(args);
     }
 }

明顯的main函數吸引了我們的注意,沒錯了,這就是入口,看看JarLauncher的空構造并沒有任何代碼,我們先往它的父類找找:

 // ExecutableArchiveLauncher.java
 public abstract class ExecutableArchiveLauncher extends Launcher {
     public ExecutableArchiveLauncher() {
         try {
             this.archive = this.createArchive();
         } catch (Exception var2) {
             throw new IllegalStateException(var2);
         }
     }
     // ...省略
 }
 
 // Launcher.java
 public abstract class Launcher {
     public Launcher() {}
     // ...省略無關代碼
 }

從代碼中可以看出,真正干了事情的父類是ExecutableArchiveLauncher,它在初始化時構造了archive實例,該實例封裝了/META-INF/MANIFEST.MF文件的信息。后面我們也會用到它。

隨后便是launch方法,我們只關系核心執行流程:

 // Launcher.java
 protected void launch(String[] args) throws Exception {
     JarFile.registerUrlProtocolHandler();
     ClassLoader classLoader = this.createClassLoader(this.getClassPathArchives());
     this.launch(args, this.getMainClass(), classLoader);
 }
 // ExecutableArchiveLauncher.java
 protected String getMainClass() throws Exception {
     Manifest manifest = this.archive.getManifest();
     String mainClass = null;
     if (manifest != null) {
         mainClass = manifest.getMainAttributes().getValue("Start-Class");
     }
 
     if (mainClass == null) {
         throw new IllegalStateException("No 'Start-Class' manifest entry specified in " + this);
     } else {
         return mainClass;
     }
 }

這里首先調用子類ExecutableArchiveLauncher的getMainClass方法,主要邏輯就是從/META-INF/MANIFEST.MF文件中獲取Start-Class信息,對應上文就是com.vivo.internet.nex.repeater.console.RepeaterConsoleApplication字符串,這樣就和我們寫的啟動類關聯上了。

然后是launch方法的具體執行,launch()首先創建一個MainMethodRunner,將上文獲取的Start-Class和透傳的參數傳遞進去,然后調用MainMethodRunner的run方法。run方法的執行也非常簡單,就是加載Start-Class對應的啟動類,然后反射調用啟動類的main方法。之后就是容器的初始化過程了。

 // Launcher.java
 protected void launch(String[] args, String mainClass, ClassLoader classLoader) throws Exception {
     Thread.currentThread().setContextClassLoader(classLoader);
     // 這里首先調用createMainMethodRunner創建一個MainMethodRunner實例,將mainClass和args參數傳入。隨后調用
     this.createMainMethodRunner(mainClass, args, classLoader).run();
 }
 protected MainMethodRunner createMainMethodRunner(String mainClass, String[] args, ClassLoader classLoader) {
     return new MainMethodRunner(mainClass, args);
 }
 
 // MainMethodRunner.java
 public MainMethodRunner(String mainClass, String[] args) {
     this.mainClassName = mainClass;
     this.args = args != null ? (String[])args.clone() : null;
 }
 public void run() throws Exception {
     Class<?> mainClass = Thread.currentThread().getContextClassLoader().loadClass(this.mainClassName);
     Method mainMethod = mainClass.getDeclaredMethod("main", String[].class);
     mainMethod.invoke((Object)null, this.args);
 }

關于“SpringBoot應用的啟動入口怎么封裝”這篇文章的內容就介紹到這里,感謝各位的閱讀!相信大家對“SpringBoot應用的啟動入口怎么封裝”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

巩留县| 普宁市| 乐清市| 建宁县| 南江县| 山丹县| 昔阳县| 张家口市| 辽中县| 通河县| 台南县| 屯留县| 古浪县| 灌阳县| 康马县| 木兰县| 石楼县| 桦川县| 张掖市| 红河县| 攀枝花市| 曲靖市| 泾川县| 理塘县| 驻马店市| 手游| 贵溪市| 宁陕县| 册亨县| 平远县| 阿合奇县| 南溪县| 安乡县| 略阳县| 丘北县| 璧山县| 绍兴市| 高阳县| 酉阳| 五莲县| 刚察县|