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

SpringBoot的java -jar命令啟動(dòng)原理解讀

 更新時(shí)間:2024年02月26日 11:03:40   作者:寒山道杳  
這篇文章主要介紹了SpringBoot的java -jar命令啟動(dòng)原理,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

導(dǎo)語

在運(yùn)用Spring Boot 后,我們基本上擺脫之前項(xiàng)目每次上線的時(shí)候把項(xiàng)目打成war包。

當(dāng)然也不排除一些奇葩的規(guī)定,必須要用war包上線,不過很多時(shí)候,我們對(duì)一些東西只是處在使用的階段,并不會(huì)去深入的研究使用的原理是什么,這貌似也是大多數(shù)人的固定思維。

或許正是如此,總會(huì)有些沒有固定思維的人會(huì)去積極的探索原理,當(dāng)然這話不是說我是積極的,我其實(shí)也是只原理的搬運(yùn)工。

今天和大家來簡單的說下Spring Boot 的項(xiàng)目在運(yùn)行Java -jar的原理。

jar包目錄和jar命令啟動(dòng)入口

在正式開始之前,我們先來看看把jar包進(jìn)行解壓。

然后用tree /f命令查看目錄結(jié)構(gòu)(由于筆者寫博文時(shí)用的是window,所以用的是tree /f命令),由于目錄結(jié)構(gòu)太長,這里做了相應(yīng)省略,如下:

├─BOOT-INF
│  ├─classes
│  │  │  application.properties
│  │  │
│  │  └─com
│  │      └─spring
│  │          └─boot
│  │              └─test
│  │                      SpringBootTestApplication.class
│  │
│  └─lib
│          classmate-1.5.1.jar
│          hibernate-validator-6.0.18.Final.jar
│          …………此處省略…………
│
├─META-INF
│  │  MANIFEST.MF
│  │
│  └─maven
│      └─com.spring.boot.test
│          └─spring-boot-test
│                  pom.properties
│                  pom.xml
│
└─org
    └─springframework
        └─boot
            └─loader
                │  ExecutableArchiveLauncher.class
                │  JarLauncher.class
                │  LaunchedURLClassLoader$UseFastConnectionExceptionsEnumeration.class
                │  LaunchedURLClassLoader.class
                │  Launcher.class
                │  MainMethodRunner.class
                │  PropertiesLauncher$1.class
                │  PropertiesLauncher$ArchiveEntryFilter.class
                │  PropertiesLauncher$PrefixMatchingArchiveFilter.class
                │  PropertiesLauncher.class
                │  WarLauncher.class
                │
                ├─archive
                │      Archive$Entry.class
                │      …………此處省略…………
                │
                ├─data
                │      RandomAccessData.class
                │      …………此處省略…………
                │
                ├─jar
                │      AsciiBytes.class
                │      Bytes.class
                │      …………此處省略…………
                │
                └─util
                        SystemPropertyUtils.class

先簡單說下上面目錄結(jié)構(gòu),大體目錄分三層:BOOT-INF、META-INF、org,BOOT-INF是存放對(duì)應(yīng)的應(yīng)用服務(wù)的.class文件和Maven依賴的jar包,包括啟動(dòng)類SpringBootTestApplication,META-INF下存放的是Maven相關(guān)的pom信息和MANIFEST.MF文件,org文件夾下存放的是Spring boot loader模塊編譯的.class文件,也就是jar啟動(dòng)的關(guān)鍵代碼所在。

在執(zhí)行java -jar命令的時(shí)候,它的啟動(dòng)類配置實(shí)在jar包目錄下META-INF文件夾下的名MANIFEST.MF文件中,在這個(gè)文件中有一個(gè)名為Main-Class的屬性,我們來看下這個(gè)文件的具體內(nèi)容:

Manifest-Version: 1.0
Implementation-Title: spring-boot-test
Implementation-Version: 0.0.1-SNAPSHOT
Start-Class: com.spring.boot.test.SpringBootTestApplication
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Build-Jdk-Spec: 1.8
Spring-Boot-Version: 2.2.3.RELEASE
Created-By: Maven Archiver 3.4.0
Main-Class: org.springframework.boot.loader.JarLauncher

從上面的配置文件中,可以看到Main-Class屬性指向的Class為org.springframework.boot.loader.JarLauncher,而JarLauncherJAR的啟動(dòng)器,這個(gè)類是在org/springframework/boot/loader/,然后可以看到項(xiàng)目所定義的啟動(dòng)類是指向Start-Class這個(gè)屬性的。

JAR文件啟動(dòng)器——JarLauncher

在上面我們說了JarLauncher是JAR可執(zhí)行的啟動(dòng)器,那么它和項(xiàng)目的啟動(dòng)類SpringBootTestApplication有什么關(guān)聯(lián)呢?

先給大家來個(gè)示例,先來到解壓目錄下執(zhí)行命令:java org.springframework.boot.loader.JarLauncher ,然后便是如下界面:

C:\Users\elisha\Desktop\spring-boot-test-0.0.1-SNAPSHOT>java org.springframework.boot.loader.JarLauncher
 
  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.2.3.RELEASE)
2020-01-18 14:28:19.866  INFO 3644 --- [           main] c.s.boot.test.SpringBootTestApplication  : Starting SpringBootTestApplication on LAPTOP-R2NNI9CM with PID 3644 (C:\Users\elisha\Desktop\spring-boot-test-0.0.1-SNAPSHOT\BOOT-INF\classes started by elisha in C:\Users\elisha\Desktop\spring-boot-test-0.0.1-SNAPSHOT)

從上面的執(zhí)行接口可以看到項(xiàng)目引導(dǎo)類SpringBootTestApplication會(huì)被JarLauncher類進(jìn)行引導(dǎo),但是如果我們到BOOT-INF/class目錄下,然后也執(zhí)行java  com.spring.boot.test.SpringBootTestApplication,會(huì)報(bào)SpringApplication的ClassNotFoundException這個(gè)錯(cuò)誤,由此可以得知這是因?yàn)閖ava命令未指定Class Path。

不過當(dāng)前Spring Boot依賴的JAR文件都是存放在BOOT-INF/lib下,而org.springframework.boot.loader.JarLauncher會(huì)將JAR作為SpringBootTestApplication類庫的依賴,這也就是為什么JarLauncher能引導(dǎo)SpringBootTestApplication,反之則是不可以的,那么對(duì)于SpringBootTestApplicationJarLauncher的子進(jìn)程,還是處于同一層級(jí)呢?

接下來我們來看看JarLauncher的原理。

JarLauncher實(shí)現(xiàn)引導(dǎo)原理

因?yàn)?strong>org.springframework.boot.loader.JarLauncher的類是在spring-boot-loader中,但是若想在IDEA中來看源碼,需要在pom文件中引入如下配置:

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

在引入上面的配置文件后,便可以在IDEA中查看源碼了,使用CTRL+N命令來搜索JarLauncher類,那就來看下源碼,如下:

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);
	}
 
	@Override
	protected boolean isNestedArchive(Archive.Entry entry) {
		if (entry.isDirectory()) {
			return entry.getName().equals(BOOT_INF_CLASSES);
		}
		return entry.getName().startsWith(BOOT_INF_LIB);
	}
 
	public static void main(String[] args) throws Exception {
		new JarLauncher().launch(args);
	}
 
}

從上面的JarLauncher類中,可以看到兩個(gè)常量:BOOT_INF_CLASSES、BOOT_INF_LIB,而它們又分別指向如下路徑:BOOT-INF/classes/、BOOT-INF/lib/,并用isNestedArchive(Archive.Entry entry)方法進(jìn)行判斷(在Spring Boot中Archive,抽象出了Archive的概念,一個(gè)Archive可以是一個(gè)Jar(JarFileArchive)、也可以是一個(gè)目錄(ExplodedArchive),在這里可以理解為Spring  Boot抽象出來的同一訪問資源層。),從isNestedArchive方法的參數(shù)Archive.Entry對(duì)象貌似為一個(gè)JAR文件中的資源,譬如application.properties,同時(shí)這個(gè)對(duì)象和JarEntry是類似的,其name屬性(Archive.Entry#getName())便是Jar資源的相對(duì)路徑。當(dāng)application.properties資源在FAT JAR目錄下時(shí),其實(shí)Archive.Entry#getName()就是/BOOT-INF/classes/application.properties,此時(shí)便符合startsWith方法的判斷,所以isNestedArchive(Archive.Entry entry)便返回為true。

當(dāng)返回為false時(shí),便說明FAT JAR被解壓到文件目錄了,由此也說明了Spring Boot應(yīng)用可以通過java org.springframework.boot.loader.JarLauncher 命令啟動(dòng)的原因了。

Archive.Entry的實(shí)現(xiàn)

上面說了在Spring Boot中Archive,抽象出了Archive的概念,一個(gè)Archive可以是一個(gè)Jar(JarFileArchive)、也可以是一個(gè)目錄(ExplodedArchive),這里所說的JarFileArchive、ExplodedArchive便是Archive的兩種是想方式,對(duì)于這兩個(gè)類的實(shí)現(xiàn)代碼感興趣額同學(xué)可以自己去看看。

不過由此也說明了JarLauncher  既支持JAR啟動(dòng),又支持文件系統(tǒng)啟動(dòng)。

同時(shí)JarLauncher 在作為引導(dǎo)類的時(shí)候,當(dāng)執(zhí)行java -jar 命令式,/META-INF/ 下MANIFEST.MF文件中的Main-Class屬性將調(diào)用它的,main(String [])方法,其實(shí)它還是調(diào)用JarLauncher #launch(args)方法,這個(gè)方法是實(shí)現(xiàn)基類Launcher,這里簡單看下這個(gè)方法的實(shí)現(xiàn):

protected void launch(String[] args) throws Exception {
	JarFile.registerUrlProtocolHandler();
	ClassLoader classLoader = createClassLoader(getClassPathArchives());
	launch(args, getMainClass(), classLoader);
}

總結(jié)

本篇文章簡單的講解了一下,java -jar命令的一個(gè)執(zhí)行的原理,首先說了下jar包目錄和jar命令啟動(dòng)入口,然后說了下JAR文件啟動(dòng)器——JarLauncher和JarLauncher實(shí)現(xiàn)引導(dǎo)原理,最后說了下Archive.Entry的實(shí)現(xiàn),這個(gè)實(shí)現(xiàn)的原理也是比較復(fù)雜,后面如果有機(jī)會(huì),會(huì)再寫篇文章來進(jìn)行說明。

這些僅為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • SpringBoot整合JPA框架實(shí)現(xiàn)過程講解

    SpringBoot整合JPA框架實(shí)現(xiàn)過程講解

    在開發(fā)中,我們通常會(huì)對(duì)數(shù)據(jù)庫的數(shù)據(jù)進(jìn)行操作,Sprirng?Boot對(duì)關(guān)系型數(shù)據(jù)庫和非關(guān)系型數(shù)據(jù)庫的訪問操作都提供了非常好的整合支持
    2022-12-12
  • Mybatis關(guān)聯(lián)查詢遇到的坑-無主鍵的關(guān)聯(lián)數(shù)據(jù)去重問題

    Mybatis關(guān)聯(lián)查詢遇到的坑-無主鍵的關(guān)聯(lián)數(shù)據(jù)去重問題

    這篇文章主要介紹了Mybatis關(guān)聯(lián)查詢遇到的坑-無主鍵的關(guān)聯(lián)數(shù)據(jù)去重問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • spring.profiles使用的方法步驟

    spring.profiles使用的方法步驟

    本文主要介紹了spring.profiles使用與spring.profiles.active和spring.profiles.include區(qū)別,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07
  • Java窗口精細(xì)全方位講解

    Java窗口精細(xì)全方位講解

    這篇文章呢,將會(huì)系統(tǒng)的精細(xì)的教會(huì)鐵鐵們?nèi)绾巫约簩懸粋€(gè)完整的窗口;看完之后窗口穩(wěn)拿下!!!所以呢由于詳細(xì),知識(shí)點(diǎn)多,可能有點(diǎn)長,鐵鐵們慢慢仔細(xì)閱讀吧;文章寫的還是一如既往快樂的,哈哈哈
    2021-08-08
  • Java中Integer.valueOf,parsetInt() String.valueOf的區(qū)別和結(jié)果代碼解析

    Java中Integer.valueOf,parsetInt() String.valueOf的區(qū)別和結(jié)果代碼解析

    本文通過代碼給大家講解了JAVA中Integer.valueOf, parsetInt() String.valueOf的區(qū)別和結(jié)果,需要的朋友可以參考下
    2018-05-05
  • java 反射機(jī)制

    java 反射機(jī)制

    本文主要介紹了java反射機(jī)制的相關(guān)知識(shí),具有一定的參考價(jià)值,下面跟著小編一起來看下吧
    2017-02-02
  • java中Lamda表達(dá)式講解

    java中Lamda表達(dá)式講解

    本文詳細(xì)講解了java中的Lamda表達(dá)式,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-12-12
  • Mybatis中 SQL語句復(fù)用

    Mybatis中 SQL語句復(fù)用

    這篇文章主要介紹了Mybatis中 SQL語句復(fù)用,需要的朋友可以參考下
    2017-03-03
  • Spring多線程的使用以及問題詳解

    Spring多線程的使用以及問題詳解

    在我們開發(fā)系統(tǒng)過程中,經(jīng)常會(huì)處理一些費(fèi)時(shí)間的任務(wù)(如:向數(shù)據(jù)庫中插入大量數(shù)據(jù)),這個(gè)時(shí)候就就需要使用多線程,下面這篇文章主要給大家介紹了關(guān)于Spring多線程的使用以及問題的相關(guān)資料,需要的朋友可以參考下
    2022-05-05
  • 老生常談Java字符串進(jìn)階(必看篇)

    老生常談Java字符串進(jìn)階(必看篇)

    下面小編就為大家?guī)硪黄仙U凧ava字符串進(jìn)階(必看篇)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-06-06

最新評(píng)論

两当县| 和龙市| 仲巴县| 金坛市| 葫芦岛市| 金山区| 科技| 三穗县| 安泽县| 威远县| 江山市| 怀集县| 天峨县| 柯坪县| 永清县| 贵溪市| 大竹县| 乐亭县| 阿合奇县| 龙门县| 绥江县| 喀喇沁旗| 济宁市| 沙洋县| 宿迁市| 九龙城区| 阿荣旗| 天津市| 彰化市| 永兴县| 平乐县| 四平市| 申扎县| 永顺县| 克什克腾旗| 错那县| 朔州市| 台江县| 海安县| 宣恩县| 绿春县|