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 }

 

posted @ 2019-08-04 18:24  爱吃猫的鱼z  阅读(1905)  评论(0编辑  收藏  举报