ClassPathResource解析
先看Demo:
@Test
public void test() throws IOException {
Resource res = new ClassPathResource("applicationContext.xml");
InputStream input = res.getInputStream();
Assert.assertNotNull(input);
}
內部源碼:
public ClassPathResource(String path) {
this(path, (ClassLoader) null);
}
public ClassPathResource(String path, ClassLoader classLoader) {
Assert.notNull(path, "Path must not be null");
String pathToUse = StringUtils.cleanPath(path);
if (pathToUse.startsWith("/")) {
pathToUse = pathToUse.substring(1);
}
this.path = pathToUse;
this.classLoader = (classLoader != null ? classLoader : ClassUtils.getDefaultClassLoader());
}
public ClassPathResource(String path, Class<?> clazz) {
Assert.notNull(path, "Path must not be null");
this.path = StringUtils.cleanPath(path);
this.clazz = clazz;
}
獲取資源內容:
@Override
public InputStream getInputStream() throws IOException {
InputStream is;
if (this.clazz != null) {
is = this.clazz.getResourceAsStream(this.path);
}
else if (this.classLoader != null) {
is = this.classLoader.getResourceAsStream(this.path);
}
else {
is = ClassLoader.getSystemResourceAsStream(this.path);
}
if (is == null) {
throw new FileNotFoundException(getDescription() + " cannot be opened because it does not exist");
}
return is;
}
所以類獲取資源的方式有兩種
Class獲取和ClassLoader獲取。
兩種方法的Demo和區別:
Demo:
@Test
public void test1() {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
// ClassLoader.getResource("")獲取的是classpath的根路徑
System.out.println("a--- " + classLoader.getResource("").getPath());
// new ClassPathResource()獲取的是空路徑
System.out.println("b--- " + new ClassPathResource("/").getPath());
System.out.println("b-1--- " + new ClassPathResource("").getPath());
// Class.getResource("")獲取的是相對於當前類的相對路徑
System.out.println("c--- " + this.getClass().getResource("").getPath());
// Class.getResource("/")獲取的是classpath的根路徑
System.out.println("d--- " + this.getClass().getResource("/").getPath());
}
輸出:
a--- /E:/xie-my-install/devolop/eideaworkspace/ideatest/target/classes/
b---
b-1---
c--- /E:/xie-my-install/devolop/eideaworkspace/ideatest/target/classes/com/xie/util/
d--- /E:/xie-my-install/devolop/eideaworkspace/ideatest/target/classes/
區別
- Class.getResource("")獲取的是相對於當前類的相對路徑
- Class.getResource("/")獲取的是classpath的根路徑
- ClassLoader.getResource("")獲取的是classpath的根路徑
- new ClassPathResource("")。空路徑,如果沒有指定相對的類名,該類將從類的根路徑開始尋找某個resource,如果指定了相對的類名,則根據指定類的相對路徑來查找某個resource。
(如果打成可執行jar包的話,可以使用這種寫法在jar的同級目錄下創建文件路徑:new ClassPathResource("").getPath() + "/" + UUidUtil.getStrUUID() + ".jpg";)這個可能還沒研究透徹
- 在創建ClassPathResource對象時,我們可以指定是按Class的相對路徑獲取文件還是按ClassLoader來獲取。