Mybatis IO處理工具Resources和ClassLoaderWrapper
Resources類位於org.apache.ibatis.io包下,用於處理相關的IO操作,例如將文件,網絡資源進行讀取並轉換為File,InputStream,Reader,URL等Java類。Resources類提供了多個getResourceAsxxx()方法作為對外暴露的方法,Resources並不提供方法實現,而是內部維護着一個靜態ClassLoaderWrapper實例,Resources中的方法都是通過調用ClassLoaderWrapper相關方法實現。下面列出了Resources最常用的方法。
方法名 | 參數 |
---|---|
File getResourceAsFile() | resource,classloader |
Properties getResourceAsProperties() | resource,classloader |
Reader getResourceAsReader() | resource,classloader |
InputStream getResourceAsStream() | resource,classloader |
URL getResourceURL() | resource,classloader |
Properties getUrlAsProperties() | resource,classloader |
setCharset() | Charset |
void setDefaultClassLoader(ClassLoader) | ClassLoader |
ClassLoaderWrapper
ClassLoaderWrapper並不提供public型構造器,所以無法直接進行實例化,只能通過上述的Resources類進行獲取。該類提供了獲取資源的兩種方式,以InputStream形式讀取本地資源,以URL形式讀取本地資源。除此之外,ClassLoaderWrappe還提供了classForName()方法用於獲取類路徑對應的Class實例。下面是ClassLoaderWrapper提供的所有方法。可以看到,每種類型方法都提供了三種入參形式,其中一種方法需要提供一個ClassLoader數組,需要注意的是這種方法並不能直接調用,前兩種方法都是交給帶有classloader[]參數的方法進行實現的。如果不提供ClassLoader則設置為null。
- Class<?> classForName(String name)
- Class<?> classForName(String name, ClassLoader classLoader)
- Class<?> classForName(String name, ClassLoader[] classLoader)
- InputStream getResourceAsStream(String resource)
- InputStream getResourceAsStream(String resource, ClassLoader classLoader)
- InputStream getResourceAsStream(String resource, ClassLoader[] classLoader)
- URL getResourceAsURL(String resource)
- URL getResourceAsURL(String resource, ClassLoader classLoader)
- URL getResourceAsURL(String resource, ClassLoader[] classLoader)
- ClassLoader[] getClassLoaders(ClassLoader classLoader)
getClassLoaders()用於為getResouceAsxxx()方法提供多個加載器。前面說過,不傳入加載器數組的方法都會調用 getResourceAsxxx(String resource, ClassLoader[] classLoader)相關的方法,而獲取加載器數組的方式就是直接調用getClassLoaders()方法。
ClassLoader[] getClassLoaders(ClassLoader classLoader) { return new ClassLoader[]{ classLoader,//自定義加載器 defaultClassLoader, Thread.currentThread().getContextClassLoader(),//當前線程加載器 getClass().getClassLoader(),//類加載器 systemClassLoader//系統默認加載器 }; }
classForName()根據類路徑生成Class實例,該方法的本質是調用classloader下的forname方法進行實例化的。
1 Class<?> classForName(String name, ClassLoader[] classLoader) throws ClassNotFoundException { 2 for (ClassLoader cl : classLoader) { 3 if (null != cl) { 4 try { 5 Class<?> c = Class.forName(name, true, cl); 6 if (null != c) { 7 return c; 8 } 9 } catch (ClassNotFoundException e) { 10 // we'll ignore this until all classloaders fail to locate the class 11 } 12 } 13 } 14 throw new ClassNotFoundException("Cannot find class: " + name); 15 }
getResourceAsStream()和getResourceAsURL():這兩個方法都是獲取相關的資源,與File類不同的是,這兩個方法傳遞的參數必須是相對路徑,否則拋出異常。同classForName()一樣,必須遍歷classLoader數組,然后調用getResourceAsStream()和getResource()。
測試實例
1 package com.zzz.mybatis.io.service; 2 3 import java.io.File; 4 import java.io.IOException; 5 import java.io.InputStream; 6 import java.io.Reader; 7 import java.net.URL; 8 import java.util.Properties; 9 import org.apache.ibatis.io.Resources; 10 import org.junit.Test; 11 public class ResourcesTest { 12 @Test 13 public void TestResources() throws IOException { 14 File f=new File("d:\\work\\workspace_redis\\mybatis\\src\\main\\resources\\mybatis-mysql.properties"); 15 System.out.println(f.exists()); 16 //自定義類加載器 17 ClassLoader classLoader = new ClassLoader() { 18 }; 19 InputStream inputStream= classLoader.getResourceAsStream("./mybatis-mysql.properties"); 20 File file=Resources.getResourceAsFile(classLoader,"./mybatis-mysql.properties"); 21 System.out.println(file.exists()); 22 Reader reader=Resources.getResourceAsReader(classLoader, "./mybatis-mysql.properties"); 23 Properties properties=Resources.getResourceAsProperties(classLoader, "./mybatis-mysql.properties"); 24 System.out.println(properties.keySet().toString()); 25 URL url=Resources.getResourceURL("./mybatis-mysql.properties"); 26 System.out.println(url.getContent().toString()); 27 } 28 }