前言
我們在項目中在很多時候需要獲取到當前項目的根路徑,或者當前執行類的所在路徑,進而構建 File 對象。在正常情況下一般都是使用 XX.class.get Resource().getPath(),那么如果我們想要獲取該類所處的 jar 包呢,例如我們使用的是第三方引入 jar 包中的類,那么我們該如何獲取該類所處 jar 包的絕對路徑呢?
1. 獲取運行類的絕對路徑
使用 Class.getResource().getPath()來獲取
下面我們來看看示例
public class Test {
public static void main(String[] args) throws URISyntaxException {
System.out.println(Test.class.getResource("").getPath());
System.out.println(Test.class.getResource(".").getPath());
System.out.println(Test.class.getResource("/").getPath());
}
}
執行結果:
/D:/workspace_demo/springboot-packagejar/target/classes/com/lonely/springbootpackagejar/
/D:/workspace_demo/springboot-packagejar/target/classes/com/lonely/springbootpackagejar/
/D:/workspace_demo/springboot-packagejar/target/classes/
從結果中可以看到,在 getResource("") 和 getResource(".") 都是以指定 Class 類所處位置的絕對路徑,而如果是 getResource("/") , 則是獲取整個項目運行中的根路徑的絕對路徑。
2. 獲取運行類的所處 jar 包絕對路徑
在上面的案例中,我們知道了如何獲取指定運行類所處的絕對路徑,但是如果這個類是一個第三方的 jar 包,則該路徑會進入到該 jar 包中的具體路徑中,但是如果我們只想要獲取該類處於哪個 jar 包中怎么辦,可以使用下面的方法。
下面的代碼,是在查看 SpringBoot 源碼中以外發現,在源碼中看到使用該段代碼來加載 class 類和 lib,具體路徑在:org.springframework.boot.loader.Launcher#createArchive
Class.getProtectionDomain().getCodeSource().getLocation().toURI().getSchemeSpecificPart();
案例實現:
public class Test {
public static void main(String[] args) throws URISyntaxException {
ProtectionDomain protectionDomain = JarLauncher.class.getProtectionDomain();
CodeSource codeSource = protectionDomain.getCodeSource();
URI location = (codeSource != null) ? codeSource.getLocation().toURI() : null;
String path = (location != null) ? location.getSchemeSpecificPart() : null;
System.out.println(path);
}
}
執行結果:
/D:/workspace_demo/springboot-packagejar/target/springboot-packagejar-0.0.1-SNAPSHOT.jar
針對這個結果,可能有些朋友運行同樣的代碼會有不一樣的結果,下面來分析一波。
- 如果直接將該代碼拿到編輯器上,會提示 JarLauncher 類找不到,因為該類實際上是在 SpringBoot 工程打包后,Spring 提供的插件會將一個 jar 包的所有文件內容都放入打好的 jar 包中。而我們如果想要看源碼,需要添加依賴,如下:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-loader</artifactId>
</dependency>
- 添加好依賴后,執行上述代碼可能結果也不是如上的,可能現在該 jar 是處於自己的本地 maven 倉庫中,因為此時,你沒有把加入的依賴打入 jar 包中,需要使用命令 ----- mvn clean package 進行打入 jar 包,在執行 jar 包獲取結果。