SpringBoot程序的打包與運行的實現(xiàn)
剛開始做開發(fā)學習的小伙伴可能在有一個知識上面有錯誤的認知,我們天天寫程序是在Idea下寫的,運行也是在Idea下運行的。
但是實際開發(fā)完成后,我們的項目是不可能運行在自己的電腦上的。
我們以后制作的程序是運行在專用的服務(wù)器上的,簡單說就是將你做的程序放在一臺獨立運行的電腦上,這臺電腦要比你開發(fā)使用的計算機更專業(yè),并且安全等級各個方面要遠超過你現(xiàn)在的電腦。
那我們的程序如何放置在這臺專用的電腦上呢,這就要將我們的程序先組織成一個文件,然后將這個文件傳輸?shù)竭@臺服務(wù)器上。這里面就存在兩個過程,一個是打包的過程,另一個是運行的過程。
溫馨提示
? 企業(yè)項目上線為了保障環(huán)境適配性會采用下面流程發(fā)布項目,這里不討論此過程。
- 開發(fā)部門使用Git、SVN等版本控制工具上傳工程到版本服務(wù)器
- 服務(wù)器使用版本控制工具下載工程
- 服務(wù)器上使用Maven工具在當前真機環(huán)境下重新構(gòu)建項目
- 啟動服務(wù)
繼續(xù)說我們的打包和運行過程。所謂打包指將程序轉(zhuǎn)換成一個可執(zhí)行的文件,所謂運行指不依賴開發(fā)環(huán)境執(zhí)行打包產(chǎn)生的文件。上述兩個操作都有對應的命令可以快速執(zhí)行。
程序打包
? SpringBoot程序是基于Maven創(chuàng)建的,在Maven中提供有打包的指令,叫做package。本操作可以在Idea環(huán)境下執(zhí)行。
mvn package
? 打包后會產(chǎn)生一個與工程名類似的jar文件,其名稱是由模塊名+版本號+.jar組成的。
程序運行
? 程序包打好以后,就可以直接執(zhí)行了。在程序包所在路徑下,執(zhí)行指令。
java -jar 工程包名.jar
? 執(zhí)行程序打包指令后,程序正常運行,與在Idea下執(zhí)行程序沒有區(qū)別。
? 特別關(guān)注:如果你的計算機中沒有安裝java的jdk環(huán)境,是無法正確執(zhí)行上述操作的,因為程序執(zhí)行使用的是java指令。
? 特別關(guān)注:在使用向?qū)?chuàng)建SpringBoot工程時,pom.xml文件中會有如下配置,這一段配置千萬不能刪除,否則打包后無法正常執(zhí)行程序。
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
總結(jié)
- SpringBoot工程可以基于java環(huán)境下獨立運行jar文件啟動服務(wù)
- SpringBoot工程執(zhí)行mvn命令package進行打包
- 執(zhí)行jar命令:java –jar 工程名.jar
SpringBoot程序打包失敗處理
? 有些小伙伴打包以后執(zhí)行會出現(xiàn)一些問題,導致程序無法正常執(zhí)行,例如下面的現(xiàn)象
要想搞清楚這個問題就要說說.jar文件的工作機制了,知道了這個東西就知道如何避免此類問題的發(fā)生了。
搞java開發(fā)平時會接觸很多jar包,比如mysql的驅(qū)動jar包,而上面我們打包程序后得到的也是一個jar文件。這個時候如果你使用上面的java -jar指令去執(zhí)行mysql的驅(qū)動jar包就會出現(xiàn)上述不可執(zhí)行的現(xiàn)象,而我們的SpringBoot項目為什么能執(zhí)行呢?其實是因為打包方式不一樣。
在SpringBoot工程的pom.xml中有下面這組配置,這組配置決定了打包出來的程序包是否可以執(zhí)行。
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
我們分別開啟這段配置和注釋掉這段配置分別執(zhí)行兩次打包,然后觀察兩次打包后的程序包的差別,共有3處比較明顯的特征
- 打包后文件的大小不同
- 打包后所包含的內(nèi)容不同
- 打包程序中個別文件內(nèi)容不同
? 先看第一個現(xiàn)象,文件大小不同。帶有配置時打包生成的程序包大小如下:
不難看出,帶有配置的程序包體積比不帶配置的大了30倍,那這里面都有什么呢?能差這么多?下面看看里面的內(nèi)容有什么區(qū)別。
我們發(fā)現(xiàn)內(nèi)容也完全不一樣,僅有一個目錄是一樣的,叫做META-INF。打開容量大的程序包中的BOOT-INF目錄下的classes目錄,我們發(fā)現(xiàn)其中的內(nèi)容居然和容量小的程序包中的內(nèi)容完全一樣。
? 原來大的程序包中除了包含小的程序包中的內(nèi)容,還有別的東西。都有什么呢?回到BOOT-INF目錄下,打開lib目錄,里面顯示了很多個jar文件。
仔細翻閱不難發(fā)現(xiàn),這些jar文件都是我們制作這個工程時導入的坐標對應的文件。大概可以想明白了,SpringBoot程序為了讓自己打包生成的程序可以獨立運行,不僅將項目中自己開發(fā)的內(nèi)容進行了打包,還把當前工程運行需要使用的jar包全部打包進來了。為什么這樣做呢?就是為了可以獨立運行。不依賴程序包外部的任何資源可以獨立運行當前程序。這也是為什么大的程序包容量是小的程序包容量的30倍的主要原因。
再看看大程序包還有什么不同之處,在最外層目錄包含一個org目錄,進入此目錄,目錄名是org\springframework\boot\loader,在里面可以找到一個JarLauncher.class的文件,先記得這個文件。再看這套目錄名,明顯是一個Spring的目錄名,為什么要把Spring框架的東西打包到這個程序包中呢?
回到兩個程序包的最外層目錄,查看名稱相同的文件夾META-INF下都有一個叫做MANIFEST.MF的文件,但是大小不同,打開文件,比較內(nèi)容區(qū)別
小容量文件的MANIFEST.MF
Manifest-Version: 1.0 Implementation-Title: springboot_08_ssmp Implementation-Version: 0.0.1-SNAPSHOT Build-Jdk-Spec: 1.8 Created-By: Maven Jar Plugin 3.2.0
大容量文件的MANIFEST.MF
Manifest-Version: 1.0 Spring-Boot-Classpath-Index: BOOT-INF/classpath.idx Implementation-Title: springboot_08_ssmp Implementation-Version: 0.0.1-SNAPSHOT Spring-Boot-Layers-Index: BOOT-INF/layers.idx Start-Class: com.itheima.SSMPApplication Spring-Boot-Classes: BOOT-INF/classes/ Spring-Boot-Lib: BOOT-INF/lib/ Build-Jdk-Spec: 1.8 Spring-Boot-Version: 2.5.4 Created-By: Maven Jar Plugin 3.2.0 Main-Class: org.springframework.boot.loader.JarLauncher
? 大文件中明顯比小文件中多了幾行信息,其中最后一行信息是Main-Class: org.springframework.boot.loader.JarLauncher。這句話什么意思呢?如果使用java -jar執(zhí)行此程序包,將執(zhí)行Main-Class屬性配置的類,這個類恰巧就是前面看到的那個文件。原來SpringBoot打包程序中出現(xiàn)Spring框架的東西是為這里服務(wù)的。而這個org.springframework.boot.loader.JarLauncher類內(nèi)部要查找Start-Class屬性中配置的類,并執(zhí)行對應的類。這個屬性在當前配置中也存在,對應的就是我們的引導類類名。
? 現(xiàn)在這組設(shè)定的作用就明白了:
- SpringBoot程序添加配置后會打出一個特殊的包,包含Spring框架部分功能,原始工程內(nèi)容,原始工程依賴的jar包
- 首先讀取MANIFEST.MF文件中的Main-Class屬性,用來標記執(zhí)行java -jar命令后運行的類
- JarLauncher類執(zhí)行時會找到Start-Class屬性,也就是啟動類類名
- 運行啟動類時會運行當前工程的內(nèi)容
- 運行當前工程時會使用依賴的jar包,從lib目錄中查找
看來SpringBoot打出來了包為了能夠獨立運行,簡直是煞費苦心,將所有需要使用的資源全部都添加到了這個包里。這就是為什么這個jar包能獨立運行的原因。
再來看之前的報錯信息:
由于打包時沒有使用那段配置,結(jié)果打包后形成了一個普通的jar包,在MANIFEST.MF文件中也就沒有了Main-Class對應的屬性了,所以運行時提示找不到主清單屬性,這就是報錯的原因。
總結(jié)
spring-boot-maven-plugin插件用于將當前程序打包成一個可以獨立運行的程序包
命令行啟動常見問題及解決方案
? 各位小伙伴在DOS環(huán)境下啟動SpringBoot工程時,可能會遇到端口占用的問題。給大家一組命令,不用深入學習,備用吧。
# 查詢端口 netstat -ano # 查詢指定端口 netstat -ano |findstr "端口號" # 根據(jù)進程PID查詢進程名稱 tasklist |findstr "進程PID號" # 根據(jù)PID殺死任務(wù) taskkill /F /PID "進程PID號" # 根據(jù)進程名稱殺死任務(wù) taskkill -f -t -im "進程名稱"
SpringBoot項目快速啟動(Linux版)
? 其實對于Linux系統(tǒng)下的程序運行與Windows系統(tǒng)下的程序運行差別不大,命令還是那組命令,只不過各位小伙伴可能對Linux指令不太熟悉,結(jié)果就會導致各種各樣的問題發(fā)生。比如防火墻如何關(guān)閉,IP地址如何查詢,JDK如何安裝等等。
到此這篇關(guān)于SpringBoot程序的打包與運行的實現(xiàn)的文章就介紹到這了,更多相關(guān)SpringBoot程序打包與運行內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解Mybatis中的 ${} 和 #{}區(qū)別與用法
這篇文章主要介紹了Mybatis中的 ${} 和 #{}區(qū)別與用法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-07-07Java 并發(fā)編程:volatile的使用及其原理解析
下面小編就為大家?guī)硪黄狫ava 并發(fā)編程:volatile的使用及其原理解析。小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-05-05