最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot工程打包后執(zhí)行Java?-Jar就能啟動的步驟原理

 更新時間:2023年05月15日 09:43:50   作者:softbook  
這篇文章主要介紹了SpringBoot工程打包后為何執(zhí)行Java?-Jar就能啟動,本文結(jié)合實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下

本文主要分享SpringBoot工程項目如何打包成一個可直接通過java -jar執(zhí)行的jar,并且簡單分析其啟動步驟原理。

1.SpringBoot如何打包成一個可執(zhí)行jar?

SpringBoot打包成成一個可執(zhí)行jar需要依賴一個maven打包插件spring-boot-maven-plugin,如下所示在pom文件結(jié)尾的build節(jié)點添加依賴,同時將src/main/javasrc/main/resources打入jar里面。

 	<build>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.*</include>
                </includes>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.*</include>
                </includes>
            </resource>
        </resources>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

此時再執(zhí)行maven package打包成jar(最后打包完成在target目錄下):

此時我們直接通過cmd控制臺執(zhí)行命令:java -jar boot-first-1.0.0-SNAPSHOT.jar 可以看到啟動成功。

相關(guān)日志已經(jīng)打印出來了,此時我們再通過postman驗證一下編碼中的接口是否生效:

程序中的接口代碼如下:

2.SpringBoot打包成的jar為何可以直接Java -jar執(zhí)行?

java程序的入口是main方法 ,如果一個jar能夠通過java -jar執(zhí)行起來,肯定離不開main方法。那springboot通過spring-boot-maven-plugin插件打包成的jar通常稱為fat jar,里面不僅僅包含了程序代碼還包括其他引用的依賴的jar。那這個fat jar的main方法入口在哪兒呢?我們通過解壓該jar可以看到,在META-INF下的有一個MANIFEST.MF文件:

其中MANIFEST.MF中內(nèi)容如下,其中比較重要的幾行信息:

Start-Class: com.xren.bootfirst.BootFirstApplication ##程序開始類
Spring-Boot-Classes: BOOT-INF/classes/        ##加載的class
Spring-Boot-Lib: BOOT-INF/lib/   ##加載的內(nèi)部jar位置
Main-Class: org.springframework.boot.loader.JarLauncher  ## boot啟動類

綜上可知,SpringBoot項目通過引入打包插件spring-boot-maven-plugin生成特定的主清單文件MANIFEST.MF,其中包含了程序的入口類和相關(guān)啟動依賴。

3.一窺SpringBoot初啟動

通用的jar包如果能被java -jar執(zhí)行,只需要其MANIFEST.MF文件中有 Main-Class配置項即可。而此處SpringBoot的jar中的MANIFEST.MF文件里面不僅僅包含Main-Class 還有Start-Class、Spring-Boot-Classes、Spring-Boot-Lib等相關(guān)信息,那他們是如何運行的呢?我們還是要回到該jar主類org.springframework.boot.loader.JarLauncher來一窺究竟。

查看org.springframework.boot.loader.JarLauncher類需要pom引入spring-boot-loader,如下:

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-loader</artifactId>
            <version>2.2.7.RELEASE</version>
	</dependency>

引入后其中JarLaunche類代碼如下,它包含一個main方法,并且繼承一個父類ExecutableArchiveLauncher。

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() {
    }
    protected JarLauncher(Archive archive) {
        super(archive);
    }
    protected boolean isNestedArchive(Entry entry) {
        return entry.isDirectory() ? entry.getName().equals("BOOT-INF/classes/") : entry.getName().startsWith("BOOT-INF/lib/");
    }
    public static void main(String[] args) throws Exception {
        (new JarLauncher()).launch(args);
    }
}

從main方法進入我們需要關(guān)注一個launch方法,其中的三行

  • 注冊一個jar處理類
  • 獲取一個類加載器(通過路徑加載lib和classs)
  • 通過獲取主啟動類和類加載器運行啟動。
 protected void launch(String[] args) throws Exception {
        JarFile.registerUrlProtocolHandler();
        ClassLoader classLoader = this.createClassLoader(this.getClassPathArchives());
        this.launch(args, this.getMainClass(), classLoader);
    }

追尋this.getMainClass() 方法,其會指向上述的父類ExecutableArchiveLauncher中,此處就回到了我們開始說的Start-Class配置項。

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;
        }
    }

getMainClass()方法中的this.archive.getManifest() 就是獲取jar下的META-INF/MANIFEST.MF文件。此處追尋到Archive的子類ExplodedArchive中,如下代碼獲取清單文件:

 	private File getManifestFile(File root) {
        File metaInf = new File(root, "META-INF");
        return new File(metaInf, "MANIFEST.MF");
    }

到此時清單文件中的Start-Class、Spring-Boot-Classes、Spring-Boot-Lib都已找到,準(zhǔn)備啟動!
回到org.springframework.boot.loader.Launcher的launch方法。

  • 當(dāng)前線程設(shè)置類加載器
  • 創(chuàng)建主方法并運行(主方法即為Start-Class指向的類)
protected void launch(String[] args, String mainClass, ClassLoader classLoader) throws Exception {
        Thread.currentThread().setContextClassLoader(classLoader);
        this.createMainMethodRunner(mainClass, args, classLoader).run();
    }

以上兩行代碼具體實現(xiàn)在org.springframework.boot.loader.MainMethodRunner類中,run方法即為最后的啟動邏輯

  • 通過當(dāng)前線程類加載器載入清單文件Start-Class配置的主類。
  • 加載后獲取主類中的main方法(XXXApplication中的main方法)。
  • 反射執(zhí)行該XXXApplication中的main方法。
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);
    }

至此,從執(zhí)行java -jar命令,SpringBoot打包的jar啟動到程序中XXXApplication中的main方法這一階段我們就初步分析完了!

總結(jié):SpringBoot通過引入打包插件spring-boot-maven-plugin將其相關(guān)信息寫入到j(luò)ava-jar的META-INF/MANIFEST.MF文件中,而后通過清單文件中的主入口Main-Class配置的org.springframework.boot.loader.JarLauncher類加載相關(guān)class、lib和應(yīng)用程序主類Start-Class配置的XXXApplication類,再反射獲取XXXApplication類中我們業(yè)務(wù)定義的main方法啟動運行。

到此這篇關(guān)于SpringBoot工程打包后為何執(zhí)行Java -Jar就能啟動?的文章就介紹到這了,更多相關(guān)springboot打包執(zhí)行ava -Jar啟動內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • jpa?onetomany?使用級連表刪除被維護表數(shù)據(jù)時的坑

    jpa?onetomany?使用級連表刪除被維護表數(shù)據(jù)時的坑

    這篇文章主要介紹了jpa?onetomany?使用級連表刪除被維護表數(shù)據(jù)時的坑,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • SpringMvc中的Bean加載機制詳解

    SpringMvc中的Bean加載機制詳解

    這篇文章主要介紹了SpringMvc中的Bean加載機制詳解,在Spring MVC中,Bean的作用主要是處理應(yīng)用程序的業(yè)務(wù)邏輯和數(shù)據(jù),例如,一個用戶管理應(yīng)用程序的Bean可能包括UserService、UserDao和UserController等,需要的朋友可以參考下
    2023-12-12
  • 關(guān)于java String中intern的深入講解

    關(guān)于java String中intern的深入講解

    這篇文章主要給大家介紹了關(guān)于java String中intern的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家學(xué)習(xí)或者使用java具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • idea配置springboot熱部署終極解決辦法(解決熱部署失效問題)

    idea配置springboot熱部署終極解決辦法(解決熱部署失效問題)

    這篇文章主要介紹了idea配置springboot熱部署終極解決辦法(解決熱部署失效問題),本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2020-07-07
  • java實現(xiàn)簡單的驗證碼功能

    java實現(xiàn)簡單的驗證碼功能

    這篇文章主要為大家詳細介紹了java實現(xiàn)簡單的驗證碼功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-04-04
  • 詳解Java8 新特性之日期API

    詳解Java8 新特性之日期API

    Java 8 在包java.time下包含了一組全新的時間日期API。下面通過示例給大家講解java8 新特征日期api的相關(guān)知識,感興趣的朋友一起看看吧
    2017-07-07
  • java數(shù)據(jù)結(jié)構(gòu)與算法之桶排序?qū)崿F(xiàn)方法詳解

    java數(shù)據(jù)結(jié)構(gòu)與算法之桶排序?qū)崿F(xiàn)方法詳解

    這篇文章主要介紹了java數(shù)據(jù)結(jié)構(gòu)與算法之桶排序?qū)崿F(xiàn)方法,結(jié)合具體實例形式詳細分析了桶排序的概念、原理、實現(xiàn)方法與相關(guān)操作技巧,需要的朋友可以參考下
    2017-05-05
  • Java?入門圖形用戶界面設(shè)計之事件處理下

    Java?入門圖形用戶界面設(shè)計之事件處理下

    圖形界面(簡稱GUI)是指采用圖形方式顯示的計算機操作用戶界面。與早期計算機使用的命令行界面相比,圖形界面對于用戶來說在視覺上更易于接受,本篇精講Java語言中關(guān)于圖形用戶界面的事件處理
    2022-02-02
  • Java中Spring的Security使用詳解

    Java中Spring的Security使用詳解

    這篇文章主要介紹了Java中Spring的Security使用詳解,在web應(yīng)用開發(fā)中,安全無疑是十分重要的,選擇Spring Security來保護web應(yīng)用是一個非常好的選擇,需要的朋友可以參考下
    2023-07-07
  • 在Spring項目中引入高版本依賴并解決低版本沖突問題的解決方法

    在Spring項目中引入高版本依賴并解決低版本沖突問題的解決方法

    在Spring項目的開發(fā)過程中,依賴管理是一個非常重要且復(fù)雜的問題,我們可能需要引入更高版本的依賴來使用新特性或修復(fù)舊版本的Bug,然而,這些高版本依賴可能會與項目中已有的低版本依賴產(chǎn)生沖突,本文將詳細探討如何在Spring中引入高版本依賴,并解決低版本依賴沖突的問題
    2025-03-03

最新評論

依兰县| 威海市| 九江市| 阳江市| 洛宁县| 句容市| 阿拉善左旗| 陆川县| 衡东县| 本溪| 咸宁市| 航空| 永嘉县| 阳东县| 潼关县| 饶阳县| 郎溪县| 静宁县| 安吉县| 尉氏县| 清河县| 抚顺市| 江都市| 民丰县| 井陉县| 巴林左旗| 通榆县| 台山市| 开江县| 旺苍县| 建水县| 米易县| 汕头市| 衡阳县| 海伦市| 高碑店市| 汾阳市| 石嘴山市| 富宁县| 阿坝县| 枣庄市|