亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

SpringBoot應(yīng)用能直接運(yùn)行java -jar的原因分析

 更新時(shí)間:2024年03月06日 09:45:36   作者:hbqst  
這篇文章主要介紹了SpringBoot應(yīng)用為什么能直接運(yùn)行java -jar,首先明確一點(diǎn),普通jar包是不能直接運(yùn)行的,比如工具類(lèi)jar,要能運(yùn)行,至少得要一個(gè)main函數(shù)作為入口吧?本文給大家介紹了詳細(xì)的原因分析,需要的朋友可以參考下

首先明確一點(diǎn),普通jar包是不能直接運(yùn)行的,比如工具類(lèi)jar

要能運(yùn)行,至少得要一個(gè)main函數(shù)作為入口吧?

SpringBoot應(yīng)用確實(shí)有個(gè)main函數(shù),那么問(wèn)題來(lái)了,java -jar是怎么找到這個(gè)main函數(shù)運(yùn)行的?

先說(shuō)答案

是因?yàn)橐肓藄pring-boot-maven-plugin插件

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

不信?

現(xiàn)在不使用這個(gè)插件,將SpringBoot應(yīng)用打個(gè)jar包

target目錄產(chǎn)出文件如下

在這里插入圖片描述

注意此時(shí)的jar體積為3202KB,內(nèi)容只包含了項(xiàng)目中的代碼和resources下的文件

在這里插入圖片描述

嘗試java -jar運(yùn)行,報(bào)錯(cuò)沒(méi)有主清單屬性

在這里插入圖片描述

這是把spring-boot-maven-plugin插件加上,再次打包

target目錄如下

在這里插入圖片描述

jar包體積變大了!另外多出一個(gè)jar.origin,大小和之前jar包的一樣

當(dāng)然我們只需要關(guān)系jar即可

查看jar包中的內(nèi)容,不僅包含了自己寫(xiě)的類(lèi)(classes),還將依賴的第三方j(luò)ar包全部裝了進(jìn)來(lái)(lib),這種jar被稱為fat jar

在這里插入圖片描述

這時(shí)使用java -jar命令,成功運(yùn)行!

在這里插入圖片描述

按照常規(guī)思路,一定是要找到main方法所在的這個(gè)類(lèi),然后去運(yùn)行里面的main方法

其實(shí),當(dāng)執(zhí)行java -jar時(shí),會(huì)自動(dòng)去找一個(gè)叫MANIFEST.MF的文件,然后根據(jù)其中的Main-Class找到入口類(lèi),并執(zhí)行其中的main方法

在這里插入圖片描述

而SpringBoot的jar包的這個(gè)文件,就是spring-boot-maven-plugin這個(gè)插件生成的

這個(gè)文件中的內(nèi)容如下

Manifest-Version: 1.0
Spring-Boot-Classpath-Index: BOOT-INF/classpath.idx
Archiver-Version: Plexus Archiver
Built-By: yimin
Spring-Boot-Layers-Index: BOOT-INF/layers.idx
Start-Class: com.example.k8sdemo.K8sDemoApplication
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Spring-Boot-Version: 2.6.13
Created-By: Apache Maven 3.8.8
Build-Jdk: 1.8.0_392
Main-Class: org.springframework.boot.loader.JarLauncher

好家伙,Main-Class居然不是我們自己寫(xiě)的那個(gè)類(lèi)

而是org.springframework.boot.loader.JarLauncher

想要查看這個(gè)類(lèi),先引入以下依賴

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

JarLauncher的main函數(shù)以及方法調(diào)用如下

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

protected void launch(String[] args) throws Exception {
	if (!isExploded()) {
		JarFile.registerUrlProtocolHandler();
	}
	ClassLoader classLoader = createClassLoader(getClassPathArchivesIterator());
	String jarMode = System.getProperty("jarmode");
	String launchClass = (jarMode != null && !jarMode.isEmpty()) ? JAR_MODE_LAUNCHER : getMainClass();
	launch(args, launchClass, classLoader);
}


@Override
protected String getMainClass() throws Exception {
	String mainClass = getProperty(MAIN, "Start-Class");
	if (mainClass == null) {
		throw new IllegalStateException("No '" + MAIN + "' or 'Start-Class' specified");
	}
	return mainClass;
}


protected void launch(String[] args, String launchClass, ClassLoader classLoader) throws Exception {
	Thread.currentThread().setContextClassLoader(classLoader);
	createMainMethodRunner(launchClass, args, classLoader).run();
}


protected MainMethodRunner createMainMethodRunner(String mainClass, String[] args, ClassLoader classLoader) {
	return new MainMethodRunner(mainClass, args);
}

public void run() throws Exception {
	Class<?> mainClass = Class.forName(this.mainClassName, false, Thread.currentThread().getContextClassLoader());
	Method mainMethod = mainClass.getDeclaredMethod("main", String[].class);
	mainMethod.setAccessible(true);
	mainMethod.invoke(null, new Object[] { this.args });
}

總結(jié)一下就是

  • 創(chuàng)建一個(gè)自定義的類(lèi)加載器LaunchedURLClassLoader
  • 使用這個(gè)自定義的ClassLoader去加載我們自己寫(xiě)的main方法類(lèi),這個(gè)類(lèi)由MANIFEST.MF中Start-Class定義
  • 反射獲取main方法,然后執(zhí)行

以上就是SpringBoot應(yīng)用能直接運(yùn)行java -jar的原因分析的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot直接運(yùn)行java -jar的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論