首頁 > Java > java教程 > 主體

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

WBOY
發布: 2023-05-13 10:28:21
轉載
1446 人瀏覽過

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 文件的資訊。後面我們也會用到它。

這裡先呼叫子類別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) 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;
     }
 }
登入後複製

以上是SpringBoot應用的啟動入口怎麼封裝的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:yisu.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!