只需在pom.xml文件中添加以下插件配置,然後通過mvn clean package獲取jar包即可。
打包後,您可以通過以下命令啟動服務。
如您所見,有三個主要目錄:META-INF、BOOT-INF和org。
更重要的是最主要的。MF文件:
這個文件聲明了主類配置項:可以理解為jar包的啟動類,設置為spring-boot-loader項目的JarLauncher類來啟動Spring Boot應用。
還有壹個啟動類配置項:配置內容是我們springboot項目的主要啟動類。
由Java類和配置文件編譯的類文件保存在類文件中。
我們的項目所依賴的jar包存儲在lib目錄中。
在這個文件中,包含了springboot提供的jar包啟動類,即JarLauncher.class。
當使用java -JAR filename.jar命令啟動時,將執行JAR文件中封裝的程序。JAR文件需要包含manifest,有壹行格式為Main-Class:classname,指定壹個包含公共靜態void main (string [] args)方法的類作為程序的起點。
對應於例子中的這個項目,問題可以翻譯成:為什麽不能直接使用com。jsvc . jarlearn . jarlearnapplication類作為啟動類?
主要是因為Java沒有提供任何加載嵌套jar文件的標準方法(即加載jar本身包含的jar文件)。當您需要分發壹個無需解壓縮即可從命令行運行的自包含應用程序時,問題就出現了。
同時我試過,如果直接運行應用類,找不到主類:
因為JarlearnApplication實際上是在META-INF/maven/...在文件目錄中,將找不到它。
所以springboot以org . spring framework . boot . loader . jar launcher作為啟動類。
LaunchedURLClassLoader還被定制為加載BOOT-INF中的類文件和BOOT-INF/lib中的嵌套jar包。
我在這裏通過介紹spring-boot-loader模塊來看看JarLaunch的源代碼:
可以看到在main方法中,執行了Launch方法,change方法由JarLaunch的父類launch提供:
啟動方法主要分為三個步驟:
基本思路是將org . spring framework . boot . loader的包路徑添加到java.protocol.Handler.pkgs的環境變量中,從而使用自定義的URLStreamHandler實現類處理程序來處理jar: protocol的URL。
妳可以自己下載處理程序。
有兩種主要方法:
即getClassPathArchivesIterator和createClassLoader
首先,getClassPathArchivesIterator:
首先是isSearchCandidate,它在JarLaunch中實現:
可以看到,只處理了BOOT-INF/文件夾下的內容。
然後會通過getNestedArchives獲取嵌套的存檔,isNestedArchive方法也是由JarLaunch實現的:
基本上就是獲取BOOT-INF/classes/下的目錄和BOOT-INF/lib/下的jar文件,最後通過getNestedArchives封裝到相應的存檔中並返回。
然後是createClassLoader方法:
基本上,您通過存檔獲得所有的URL,然後創建壹個類加載器來處理這些URL。
主要通過getMainClass方法來獲取在manifest文件中配置的Start-Class:
然後通過另壹種啟動方法,開始執行:
createMainMethodRunner在這裏創建了什麽?
最後調用的其實是MainMethodRunner的run方法,其實就是通過反射來調用應用的main方法。