您好,登錄后才能下訂單哦!
這篇文章主要介紹了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應用的啟動入口怎么封裝”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。