Mybatis源碼分析:Resources


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 }

 


免責聲明!

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



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