成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

當(dāng)我們的執(zhí)行 Java -jar xxx.jar 的時候底層到底做了什么?

開發(fā) 前端
通過上面的內(nèi)容我們知道了當(dāng)我們在執(zhí)行 java -jar? 的時候,根據(jù) java? 官方規(guī)范會引導(dǎo) jar? 包里面 MANIFEST.MF? 文件中的 Main-Class? 屬性對應(yīng)的啟動類,該啟動類中必須包含 main() 方法。

大家都知道我們常用的 SpringBoot? 項(xiàng)目最終在線上運(yùn)行的時候都是通過啟動 java -jar xxx.jar 命令來運(yùn)行的。

那你有沒有想過一個問題,那就是當(dāng)我們執(zhí)行 java -jar? 命令后,到底底層做了什么就啟動了我們的 SpringBoot 應(yīng)用呢?

或者說一個 SpringBoot 的應(yīng)用到底是如何運(yùn)行起來的呢?今天阿粉就帶大家來看下。

認(rèn)識 jar

在介紹 java -jar? 運(yùn)行原理之前我們先看一下 jar? 包里面都包含了哪些內(nèi)容,我們準(zhǔn)備一個 SpringBoot? 項(xiàng)目,通過在 https://start.spring.io/ 上我們可以快速創(chuàng)建一個 SpringBoot? 項(xiàng)目,下載一個對應(yīng)版本和報名的 zip 包。

圖片

下載后的項(xiàng)目我們在 pom? 依賴?yán)锩婵梢钥吹接腥缦乱蕾嚕@個插件是我們構(gòu)建可執(zhí)行 jar? 的前提,所以如果想要打包成一個 jar? 那必須在 pom? 有增加這個插件,從 start.spring.io 上創(chuàng)建的項(xiàng)目默認(rèn)是會帶上這個插件的。

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

接下來我們執(zhí)行 mvn package?,執(zhí)行完過后在項(xiàng)目的 target? 目錄里面我們可以看到有如下兩個 jar? 包,我們分別把這兩個 jar? 解壓一下看看里面的內(nèi)容,.original? 后綴的 jar 需要把后面的 .original? 去掉就可以解壓了。jar? 文件的解壓跟我們平常的 zip? 解壓是一樣的,jar? 文件采用的是 zip? 壓縮格式存儲,所以任何可以解壓 zip? 文件的軟件都可以解壓 jar 文件。

圖片

解壓過后,我們對比兩種解壓文件,可以發(fā)現(xiàn),兩個文件夾中的內(nèi)容還是有很大區(qū)別的,如下所示,左側(cè)是 demo-jar-0.0.1-SNAPSHOT.jar? 右側(cè)是對應(yīng)的 original jar。

其中有一些相同的文件夾和文件,比如 META-INF,application.properties? 等,而且我們可以明顯的看到左側(cè)的壓縮包中有項(xiàng)目需要依賴的所有庫文件,存放于 lib 文件夾中。

圖片

所以我們可以大膽的猜測,左側(cè)的壓縮包就是 spring-boot-maven-plugin 這個插件幫我們把依賴的庫以及相應(yīng)的文件調(diào)整了一下目錄結(jié)構(gòu)而生成的,事實(shí)其實(shí)也是如此。

java -jar 原理

首先我們要知道的是這個 java -jar? 不是什么新的東西,而是 java? 本身就自帶的命令,而且 java -jar? 命令在執(zhí)行的時候,命令本身對于這個 jar? 是不是 SpringBoot? 項(xiàng)目是不感知的,只要是符合 Java? 標(biāo)準(zhǔn)規(guī)范的 jar 都可以通過這個命令啟動。

圖片

而在 Java? 官方文檔顯示,當(dāng) -jar? 參數(shù)存在的時候,jar? 文件資源里面必須包含用 Main-Class? 指定的一個啟動類,而且同樣根據(jù)規(guī)范這個資源文件 MANIFEST.MF? 必須放在 /META-INF/? 目錄下。對比我們上面解壓后的文件,可以看到在左側(cè)的資源文件 MANIFEST.MF 文件中有如圖所示的一行。

![](/Users/silence/Library/Application Support/typora-user-images/image-20221206214011822.png)

圖片

可以看到這里的 Main-Class? 屬性配置的是 org.springframework.boot.loader.JarLauncher?,而如果小伙伴更仔細(xì)一點(diǎn)的話,會發(fā)現(xiàn)我們項(xiàng)目的啟動類也在這個文件里面,是通過 Start-Class? 字段來表示的,Start-Class? 這個屬性不是 Java 官方的屬性。

由此我們先大膽的猜測一下,當(dāng)我們在執(zhí)行 java -jar? 的時候,由于我們的 jar? 里面存在 MANIFEST.MF? 文件,并且其中包含了 Main-Class? 屬性且配置了 org.springframework.boot.loader.JarLauncher? 類,通過調(diào)用 JarLauncher? 類結(jié)合 Start-Class 屬性引導(dǎo)出我們項(xiàng)目的啟動類進(jìn)行啟動。接下來我們就通過源碼來驗(yàn)證一下這個猜想。

因?yàn)?nbsp;JarLauncher? 類是在 spring-boot-loader? 模塊,所以我們在 pom 文件中增加如下依賴,就可以下載源碼進(jìn)行跟蹤了。

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-loader</artifactId>
<scope>provided</scope>
</dependency>

通過源碼我們可以看到 JarLauncher 類的代碼如下

package org.springframework.boot.loader;

import org.springframework.boot.loader.archive.Archive;
import org.springframework.boot.loader.archive.Archive.EntryFilter;

public class JarLauncher extends ExecutableArchiveLauncher {

static final EntryFilter NESTED_ARCHIVE_ENTRY_FILTER = (entry) -> {
if (entry.isDirectory()) {
return entry.getName().equals("BOOT-INF/classes/");
}
return entry.getName().startsWith("BOOT-INF/lib/");
};

public JarLauncher(){
}

protected JarLauncher(Archive archive){
super(archive);
}

@Override
protected boolean isPostProcessingClassPathArchives(){
return false;
}

@Override
protected boolean isNestedArchive(Archive.Entry entry){
return NESTED_ARCHIVE_ENTRY_FILTER.matches(entry);
}

@Override
protected String getArchiveEntryPathPrefix(){
return "BOOT-INF/";
}

public static void main(String[] args) throws Exception {
new JarLauncher().launch(args);
}

}

其中有兩個點(diǎn)我們可以關(guān)注一下,第一個是這個類有一個 main? 方法,這也是為什么 java -jar? 命令可以進(jìn)行引導(dǎo)的原因,畢竟 java? 程序都是通過 main? 方法進(jìn)行運(yùn)行的。其次是這里面有兩個路徑 BOOT-INF/classes/? 和 BOOT-INF/lib/ 這兩個路徑正好是我們的源碼路徑和第三方依賴路徑。

而 JarLauncher? 類里面的 main()? 方法主要是運(yùn)行 Launcher? 里面的 launch() 方法,這幾個類的關(guān)系圖如下所示:

圖片

跟著代碼我們可以看到最終調(diào)用的是這個 run() 方法。

圖片

圖片

而這里的參數(shù) mainClass? 和 launchClass? 都是通過通過下面的邏輯獲取的,都是通過資源文件里面的 Start-Class 來進(jìn)行獲取的,這里正是我們項(xiàng)目的啟動類,由此可以看到我們上面的猜想是正確的。

圖片

擴(kuò)展

上面的類圖當(dāng)中我們還可以看到除了有 JarLauncher? 以外還有一個 WarLauncher? 類,確實(shí)我們的 SpringBoot? 項(xiàng)目也是可以配置成 war? 進(jìn)行部署的。我們只需要將打包插件里面的 jar? 更換成 war? 即可。大家可以自行嘗試重新打包解壓進(jìn)行分析,這里 war? 包部署方式只研究學(xué)習(xí)就好了,SpringBoot? 應(yīng)用還是盡量都使用 Jar 的方式進(jìn)行部署。

總結(jié)

通過上面的內(nèi)容我們知道了當(dāng)我們在執(zhí)行 java -jar? 的時候,根據(jù) java? 官方規(guī)范會引導(dǎo) jar? 包里面 MANIFEST.MF? 文件中的 Main-Class? 屬性對應(yīng)的啟動類,該啟動類中必須包含 main() 方法。

而對于我們 SpringBoot? 項(xiàng)目構(gòu)建的 ja?r 包,除了 Main-Class? 屬性外還會有一個 Start-Class? 屬性綁定的是我們項(xiàng)目的啟動類,當(dāng)我們在執(zhí)行 java -jar? 的時候優(yōu)先引導(dǎo)的是 org.springframework.boot.loader.JarLauncher#main? 方法,該方法內(nèi)部會通過引導(dǎo) Start-Class 屬性來啟動我們的應(yīng)用代碼。

通過上面的分析相比大家對于 SpringBoot? 是如何通過 java -jar? 進(jìn)行啟動了有了一個詳細(xì)的了解,下次再有人問 ?SpringBoot 項(xiàng)目是如何啟動的,請把這篇文章轉(zhuǎn)發(fā)給他。

責(zé)任編輯:武曉燕 來源: Java極客技術(shù)
相關(guān)推薦

2019-12-24 11:19:44

容器DockerLinux

2016-11-22 23:44:56

2019-06-04 14:36:04

高并發(fā)Java架構(gòu)

2019-03-18 10:08:18

RSACRSA大會 網(wǎng)絡(luò)安全

2018-06-05 18:10:43

CTO訓(xùn)練營技術(shù)管理金融科技

2011-04-19 10:04:25

NeopPIshell網(wǎng)站后門

2022-03-11 21:28:31

部署開發(fā)服務(wù)器

2018-04-24 16:38:49

招聘經(jīng)驗(yàn)主導(dǎo)

2022-04-28 13:02:32

cpu指令編程

2014-11-11 09:17:41

2009-07-08 15:18:00

JAR文件包jar命令

2020-11-16 15:47:05

SaaS軟件轉(zhuǎn)型

2022-11-11 09:28:57

軟件設(shè)計DDD

2012-08-03 09:14:23

2021-06-23 15:12:59

WiFi路由器網(wǎng)絡(luò)

2024-07-26 08:35:29

2019-03-20 16:34:56

華為中國生態(tài)伙伴大會2AI

2017-03-07 15:43:28

編程語言函數(shù)數(shù)據(jù)結(jié)構(gòu)

2014-06-25 09:11:48

技術(shù)

2016-08-12 10:11:22

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 日韩一区二区三区视频 | 国产一区二区久久 | 狠狠的干| 日韩手机视频 | 亚洲成人av| 福利网址| 秋霞a级毛片在线看 | 中文字幕亚洲一区 | www.日韩 | 亚洲综合五月天婷婷 | 91国产精品在线 | 亚洲欧美综合 | 免费成人高清 | 欧美精品成人一区二区三区四区 | 欧美日一区 | 成人一区二 | 97超碰中文网 | 一区二区三区精品 | 国产精品一区二区在线观看 | 高清av电影 | 国产一级视频在线 | 亚洲国产一区二区三区四区 | 久久精品手机视频 | 日韩欧美国产精品 | 日韩成人在线视频 | 91一区二区| 日本韩国欧美在线观看 | 色婷婷综合久久久中字幕精品久久 | 日本成人综合 | 日韩一级免费看 | 欧美99| 天天爽夜夜骑 | 日韩高清国产一区在线 | 亚洲中午字幕 | 国产97在线看 | 免费在线观看av的网站 | 色婷婷综合在线观看 | 欧美日韩网站 | 久久91精品国产一区二区三区 | 免费观看一级特黄欧美大片 | 99一区二区|