1.Mybatis读取配置文件方法
配置文件是Mybatis重要的组成部分,它是以xml配置文件的形式存在
在系统初始化的时候,通过Resources的getResourceAsStream方法读取生成InputStream流对象
配置文件的流对象用于SqlSessionFactoryBuilder来生成SqlSessionFactory对象
String resource = "mybatis/mybatis_config.xml";InputStream config = Resources.getResourceAsStream(resource);SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(config);
2.配置文件格式
Mybatis配置文件主要包含9大类,完整的配置文件模板如下:
<?xml version="1.0" encoding="UTF-8"?>
3.Resource读取配置文件
Resources是Mybatis用来来读取资源文件的,包含了很多的读取文件的方法
我们主要看下根据文件路径读取的方法:getResourceAsStream(String);InputStream
该方法是静态方法,通过类直接调用;在方法中调用了另一个读取方法getResourceAsStream(ClassLoader loader, String resource)来获取InputStream,并设置ClassLoader为空
public static InputStream getResourceAsStream(String resource) throws IOException { return getResourceAsStream((ClassLoader)null, resource); }public static InputStream getResourceAsStream(ClassLoader loader, String resource) throws IOException { InputStream in = classLoaderWrapper.getResourceAsStream(resource, loader); if (in == null) { throw new IOException("Could not find resource " + resource); } else { return in; } }
而在在getResourceAsStream(ClassLoader loader, String resource)方法中,通过classLoaderWrapper来读取文件获得InputStream,如果文件为空则抛出IOException异常
classLoaderWrapper 是ClassLoaderWrapper的实例,在创建属性的时候进行初始化
private static ClassLoaderWrapper classLoaderWrapper = new ClassLoaderWrapper();
4.ClassLoaderWrapper加载配置文件
从上面的分析可以知道Mybatis中读取xml配置文件时,Resource类主要是通过其属性classLoaderWrapper来进行读取,classLoaderWrapper是ClassLoaderWrapper的实例
ClassLoaderWrapper中有两个ClassLoader属性:defaultClassLoader和systemClassLoader
systemClassLoader是通过构造方法初始化,其值是ClassLoader.getSystemClassLoader();
public class ClassLoaderWrapper { ClassLoader defaultClassLoader; ClassLoader systemClassLoader; ClassLoaderWrapper() { try { this.systemClassLoader = ClassLoader.getSystemClassLoader(); } catch (SecurityException var2) { } } ...}
查看其加载配置文件的方法getResourceAsStream(resource, loader),首先通过getClassLoaders方法获取ClassLoader的数组,即自定义传入的classLoader , defaultClassLoader ,当前线程的classLoader , 当前类的ClassLoader 和 系统ClassLoader组成的数组;
该调用过程中传入的classLoader为null,defaultClassLoader 没有定义,systemClassLoader 在构造方法中定义
然后调用getResourceAsStream(String resource, ClassLoader[] classLoader)方法读取文件到InputStream中,通过上述中的ClassLoader数组中的对象依次来加载配置文件,直到正确读取到文件即返回
public class ClassLoaderWrapper {...public InputStream getResourceAsStream(String resource, ClassLoader classLoader) { return this.getResourceAsStream(resource, this.getClassLoaders(classLoader)); } ClassLoader[] getClassLoaders(ClassLoader classLoader) { return new ClassLoader[]{classLoader, this.defaultClassLoader, Thread.currentThread().getContextClassLoader(), this.getClass().getClassLoader(), this.systemClassLoader}; }InputStream getResourceAsStream(String resource, ClassLoader[] classLoader) { ClassLoader[] var3 = classLoader; int var4 = classLoader.length; for(int var5 = 0; var5 < var4; ++var5) { ClassLoader cl = var3[var5]; if (null != cl) { InputStream returnValue = cl.getResourceAsStream(resource); if (null == returnValue) { returnValue = cl.getResourceAsStream("/" + resource); } if (null != returnValue) { return returnValue; } } } return null; }...}
5.总结
Mybatis中定义了Resources类来读取Mybatis配置文件,在Resources的读取方法中通过其属性ClassLoaderWrapper来进行读取,而在ClassLoaderWrapper中是通过一系列ClassLoader的getResourceAsStream()方法来加载,ClassLoader数组中按优先级从低到高的顺序依次选择加载。