Mybatis源码--Resources源码分析

1 概述

在我们使用Mybatis的时候都需要将配置文件转换成InputStream,这使用我们通常是使用Resources的getResourceAsStream函数。通过查看Resources源码的注释我们也可以发现,Resources提供了通过类加载器获取资源的功能

2 ClassLoaderWrapper类

查看Resources源码,可以看见其拥有一个ClassLoaderWrapper静态属性,再分析Resrouoces源码之前,我们先来看一看这个ClassLoaderWrapper的实现及作用。

2.1 作用

ClassLoaderWrapper是一个ClassLoader的包装器,里面包含了多个ClassLoader对象,通过调整多个类加载器的使用顺序,ClassLoaderWrapper 可以确保返回给系统使用的是正确的类加载器。ClassLoaderWrapper 会按照指定的顺序依次检测其中封装的ClassLoader对象,并从中选取第一个可用的ClassLoader 对象。

2.2 属性

ClassLoader defaultClassLoader;  //默认类加载器
ClassLoader systemClassLoader;   //系统类加载器

2.3 核心方法

(1)getClassLoaders:获取类加载器的数组

ClassLoader[] getClassLoaders(ClassLoader classLoader) {
    return new ClassLoader[]{
		
	//参数指定的类加载器
        classLoader,
		
	//系统指定的默认加载器
        defaultClassLoader,
		
	//当前线程绑定的类加载器
        Thread.currentThread().getContextClassLoader(),
		
	//当前类使用的类加载器
        getClass().getClassLoader(),
		
	//系统类加载器
        systemClassLoader};
}

(2)classForName:使用加载器加载一个指定名称的类

Class<?> classForName(String name, ClassLoader[] classLoader) throws ClassNotFoundException {

    //遍历类记载器
    for (ClassLoader cl : classLoader) {
      if (null != cl) {
        try {
          
	  //获取到指定名称的类对象
          Class<?> c = Class.forName(name, true, cl);

          if (null != c) {
            return c;
          }
        } catch (ClassNotFoundException e) {
          // we'll ignore this until all classloaders fail to locate the class
        }
      }
    }
    throw new ClassNotFoundException("Cannot find class: " + name);
}

(3)getResourceAsURL:从当前类路径获取资源的URL

URL getResourceAsURL(String resource, ClassLoader[] classLoader) {
    URL url;
    //遍历类记载器
    for (ClassLoader cl : classLoader) {
        if (null != cl) {

        //获取资源的URL
        url = cl.getResource(resource);

        if (null == url) {
          url = cl.getResource("/" + resource);
        }
        if (null != url) {
          return url;
        }
      }
    }
    return null;
 }  

(4)getResourceAsStream:获取资源的输入流

 InputStream getResourceAsStream(String resource, ClassLoader[] classLoader) {
	 
    //遍历类记载器
    for (ClassLoader cl : classLoader) {
        if (null != cl) {

        //获取资源的输入流
        InputStream returnValue = cl.getResourceAsStream(resource);

        if (null == returnValue) {
          returnValue = cl.getResourceAsStream("/" + resource);
        }	
        if (null != returnValue) {
          return returnValue;
        }
      }
    }
    return null;
  }

通过上面的源码我们可以发现,ClassLoaderWrapper其实就是使用合适的类加载器来获得需要的文件数据。

3 Resources 的函数

针对Resources的函数其实大部分都是直接调用ClassLoaderWrapper的函数来实现的,这里我们仅仅对getResourceAsProperties进行分析,其余的函数都比较简单。

public static Properties getResourceAsProperties(ClassLoader loader, String resource) throws IOException {
    Properties props = new Properties();
    InputStream in = getResourceAsStream(loader, resource);
    props.load(in);
    in.close();
    return props;
}

我们可以看见这里直接使用了Properties的load函数来从输入流中获取到Properties对象。
上面就是我们对Resources源码的分析,后面将继续分析其余工具类的源码,欢迎交流。
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值