SpringBoot項目中的classpath到底指什么?


前言

最近又在研究 SpringBoot 源碼(研究好幾次了,研究完有些用不上就忘了😅),在 SpringBoot 執行 main 方法啟動過程中,會根據 classpath 下的類信息推斷當前環境信息。這里 classpath 究竟是指哪呢,搜了中文語境下的技術文章,竟然沒有找到想要的回答,可能是問題太簡單了。本篇記錄下我的看法。

java 最基礎的 classpath

classpath,顧名思義,就是指 .class 文件所在的路徑。.class 文件由 .java 文件編譯后產生,我們用 java 命令執行.class 文件時,需要指定 jvm 去哪搜索目標 class 文件,總不能全盤掃描對吧,而指定去哪搜索就是 classpath 的含義,即:
classpath是JVM用到的一個環境變量,它用來指示JVM如何搜索class

執行 java 命令時,通過java -classpath dir或者簡寫為 java -cp dir來指定,

如果命令中沒有顯式指定,則 jvm 在當前目錄中查找,即默認為:java -cp .

可以在命令中指定多個classpath,Linux 下用分隔。jvm 會依次查找指定目錄,查找到一個之后不再繼續查找下一個,比如java -cp .:/usr/local:/tmp/work

jar 包的 classpath

我們工程中一般都會有很多 .class 文件,利用 jar 包可以將他們批量管理起來,像這樣java -cp ./demo.jar boo.Helloworld指定 jar 包為 classpath 的話,jvm 就會去這個 jar 包里面搜索需要的類。

jar包還可以包含一個特殊的/META-INF/MANIFEST.MF文件,MANIFEST.MF是純文本,可以指定Main-Class和其它信息。JVM會自動讀取這個MANIFEST.MF文件,如果存在Main-Class,我們就不必在命令行指定啟動的類名,而是用更方便的命令:

java -jar hello.jar

jar包還可以包含其它jar包,這個時候,就需要在MANIFEST.MF文件里配置classpath了。

在大型項目中,不可能手動編寫MANIFEST.MF文件,再手動創建zip包。Java社區提供了大量的開源構建工具,例如Maven,可以非常方便地創建jar包。

SpringBoot 特殊的 classpath

我們將一個基於 SpringBoot 和 Maven 開發的工程打成 jar 包,然后解壓,可以看到這樣的目錄結構:

image-20210528150316369

其中/META-INF/MANIFEST.MF就是我們上文所述的可以指定Main-Class的文件,我們打開看一下:

image-20210528150704871

其中Main-Class標識 SpringBoot 項目啟動時,使用了自己的類JarLauncher來加載 jar 包;

Spring-Boot-Classes指定了 SpringBoot 項目的業務代碼的文件夾路徑;

Spring-Boot-Lib指定了 SpringBoot 項目依賴的 jar 包的文件夾路徑

我們打開文件夾進行驗證,果然如此,SpringBoot 項目看來對搜索 jar 包的規則進行了改造:

image-20210528151119477

在 IDEA 中啟動應用時的 classpath

在 IDEA 等工具中運行 java 程序時,IDEA幫我們用命令行傳入了我們依賴的所有 jar 包,這是我項目的命令,可以看出來非常多:

image-20210528142255311

點開下圖這行灰色的就能看到完整命令了:

image-20210528142356501

參考

https://www.liaoxuefeng.com/wiki/1252599548343744/1260466914339296

https://segmentfault.com/a/1190000015802324


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM