關(guān)于springboot打包目錄全解析
一、引言
Java開發(fā)中我們使用最多的便是spring框架,比如springboot應(yīng)用。
微服務(wù)模式下,每個服務(wù)都是一個springboot應(yīng)用,都會被打包成一個可執(zhí)行jar包。
那么我們有多少人嘗試去了解過這個可執(zhí)行jar到底是什么?
它的結(jié)構(gòu)是什么樣的,我認(rèn)為大部分人是沒有關(guān)注過這個的,今天筆者就通過探索的方式,揭開可執(zhí)行jar的真面目。
二、打包項目
首先使用IDEA隨便創(chuàng)建一個spring web項目,打包一下看下target目錄

classes
展開看到如下結(jié)構(gòu),主要是把我們自己寫的.java文件編譯成的.class文件和一些配置文件.yaml或者.properties,我們常說的classpath路徑,就是這個classes文件下的路徑。

generated-sources
這個一般是用來存放框架或者工具自動生成的一些源碼或者文件的地方,比如注解Lombok等。

generated-test-sources
這個沒什么好說的,用來存放生成一些測試代碼源或者文件的地方

maven-archiver
aven-archiver是Maven內(nèi)部使用的一個組件,它屬于org.apache.maven.archiver包,主要職責(zé)在于幫助Maven插件(如maven-jar-plugin, maven-war-plugin等)創(chuàng)建和管理歸檔文件(例如JAR, WAR, EAR等)。
它處理諸如設(shè)置歸檔的元數(shù)據(jù)(如Manifest文件內(nèi)容)、收集和歸檔項目資源和編譯后的類文件等工作。

maven-status
maven-status是Maven在構(gòu)建過程中創(chuàng)建的一個臨時目錄,用于存儲構(gòu)建期間的中間狀態(tài)信息。
這個目錄的內(nèi)容主要是由Maven的maven-build-number-plugin或maven-checkstyle-plugin等插件生成的,特別是那些需要跟蹤文件狀態(tài)的插件。

surefire-reports
surefire-reports是Maven項目在執(zhí)行單元測試時生成的測試報告目錄

test-classes
這個就是測試類的生成目錄

以上就是maven打包后的目錄解析說明,接下來的這兩個單獨的文件是重點

三、可執(zhí)行jar包
首先看這個.jar.original后綴的文件,
進入target目錄下,用360解壓縮解壓下original文件解壓到自己新建的original文件夾下

使用IDEA查看,看到文件結(jié)構(gòu)如下

這個文件很小只有7kb,主要是應(yīng)用的本地資源,并不包含第三方依賴。
再看.jar結(jié)尾的文件,這個就是我們打包好的可執(zhí)行jar包,同樣的解壓到創(chuàng)建的jarExcutable文件中

在IDEA中查看結(jié)構(gòu)如下

使用terminal控制臺,輸入tree

這個文件結(jié)構(gòu)相對來說就比較復(fù)雜了,解釋下關(guān)鍵部分:
- BOOT-INF/classes:存放的是應(yīng)用編譯后的class文件
- BOOT-INF/lib:這個存放的是我們引用的所有第三方j(luò)ar包依賴
- META-INF/:存放應(yīng)用相關(guān)的元信息
- org/:存放的是springboot相關(guān)的class文件
這個和標(biāo)準(zhǔn)的java EE web應(yīng)用很相似,在java EE web應(yīng)用中class文件放在WEB-INF/classes下,依賴的jar包就放在WEB-INF/lib下,二者很相似,其實spring很多東西是在java EE web基礎(chǔ)上發(fā)展而來。
java -jar yourapplicationName.jar命令可以啟動我們的jar包,那么為什么能啟動呢?打開這個MANIFEST.MF文件內(nèi)容

內(nèi)容如下

這個JarLauncher就是可執(zhí)行JAR文件啟動器,是由以下插件spring-boot-maven-plugin追加進去的,JarLauncher是專門裝載引導(dǎo)類(啟動類)的

pom文件中引入如下依賴(實際開發(fā)不需要引入,這里是為了看源碼)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-loader</artifactId>
</dependency>
JarLauncher源碼如下:
/*
* Copyright 2012-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.loader.launch;
/**
* {@link Launcher} for JAR based archives. This launcher assumes that dependency jars are
* included inside a {@code /BOOT-INF/lib} directory and that application classes are
* included inside a {@code /BOOT-INF/classes} directory.
*
* @author Phillip Webb
* @author Andy Wilkinson
* @author Madhura Bhave
* @author Scott Frederick
* @since 3.2.0
*/
public class JarLauncher extends ExecutableArchiveLauncher {
public JarLauncher() throws Exception {
}
protected JarLauncher(Archive archive) throws Exception {
super(archive);
}
@Override
protected boolean isIncludedOnClassPath(Archive.Entry entry) {
return isLibraryFileOrClassesDirectory(entry);
}
@Override
protected String getEntryPathPrefix() {
return "BOOT-INF/";
}
static boolean isLibraryFileOrClassesDirectory(Archive.Entry entry) {
String name = entry.name();
if (entry.isDirectory()) {
return name.equals("BOOT-INF/classes/");
}
return name.startsWith("BOOT-INF/lib/");
}
public static void main(String[] args) throws Exception {
new JarLauncher().launch(args);
}
}
其中的BOOT-INF/lib/和BOOT-INF/classes/對應(yīng)我們解壓jar包后的相關(guān)文件目錄,說明JarLauncher 會從中加載文件
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
spring-cloud-gateway降級的實現(xiàn)
這篇文章主要介紹了spring-cloud-gateway降級的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04
Spring boot攔截器實現(xiàn)IP黑名單的完整步驟
這篇文章主要給大家介紹了關(guān)于Spring boot攔截器實現(xiàn)IP黑名單的完整步驟,文中通過示例代碼介紹的非常詳細,對大家學(xué)習(xí)或者使用Spring boot攔截器具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06
淺談Spring Boot 開發(fā)REST接口最佳實踐
這篇文章主要介紹了淺談Spring Boot 開發(fā)REST接口最佳實踐,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-01-01
介紹下Java Spring的核心接口,容器中Bean的實例化
這篇文章主要介紹了Spring核心接口,容器中bean的實例化過程解析及完整代碼示例,簡單分析實例化bean過程并且分享了相關(guān)實例,具有一定借鑒價值,需要的朋友可以參考下2021-09-09
詳解Java8新特性之interface中的static方法和default方法
這篇文章主要介紹了Java8新特性之interface中的static方法和default方法,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下2018-08-08
使用PageHelper插件實現(xiàn)Service層分頁
這篇文章主要為大家詳細介紹了使用PageHelper插件實現(xiàn)Service層分頁,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-04-04
SpringBoot項目啟動錯誤:找不到或無法加載主類的幾種解決方法
本文主要介紹了SpringBoot項目啟動錯誤:找不到或無法加載主類的幾種解決方法,具有一定的參考價值,感興趣的可以了解一下2025-03-03
Java并發(fā)編程中的ReentrantLock類詳解
這篇文章主要介紹了Java并發(fā)編程中的ReentrantLock類詳解,ReentrantLock是juc.locks包中的一個獨占式可重入鎖,相比synchronized,它可以創(chuàng)建多個條件等待隊列,還支持公平/非公平鎖、可中斷、超時、輪詢等特性,需要的朋友可以參考下2023-12-12

