// 资源文件路径,MyBatis配置文件String resource = "mybatis-config.xml";// 读取资源文件,获取一个输入流工具InputStream inputStream = Resources.getResourceAsStream(resource);
在 MyBatis 中利用Resource的getResourceAsStream()方法读取资源文件,在getResourceAsStream()方法内部,又去调用了ClassLoaderWrapper的getResourceAsStream方法。
ClassLoaderWrapper类中getResourceAsStream方法的源码如下:
/ 依次利用5种类加载器读取资源文件 @param resource 资源文件路径 @param classLoader 类加载器 @return 资源文件流,可能为null /InputStream getResourceAsStream(String resource, ClassLoader[] classLoader) { // 依次利用5种类加载器 for (ClassLoader cl : classLoader) { // 如果类加载器不为空 if (null != cl) { // 读取资源文件 InputStream returnValue = cl.getResourceAsStream(resource); // 如果上步读取到的内容为空,会在资源文件路径前添加斜杠,然后再次读取资源文件 if (null == returnValue) { returnValue = cl.getResourceAsStream("/" + resource); } // 如果成功读取到资源文件内容,返回资源文件流 if (null != returnValue) { return returnValue; } } } // 如果利用所有的类加载器后仍旧没有成功读取资源文件,则返回null return null;}
个中参数resource为资源文件路径,classLoader为ClassLoaderWrapper中内置的类加载器数组。

利用ClassLoaderWrapper读取资源文件或者加载类时,依次利用自定义类加载器、默认类加载器、线程高下文类加载器、MyBatis类加载器、系统类加载器。如果类加载器为空或者读取到的内容为空,会连续考试测验利用下一个类加载器。
读取资源文件时,单个类加载器实行流程如下图:
类加载器
ClassLoaderWrapper中封装了5种类加载器,这5种类加载器可以通过getClassLoaders方法获取。getClassLoaders方法代码如下所示:
/ 获取所有类加载器 @param classLoader 自定义类加载器 @return 所有类加载器 /ClassLoader[] getClassLoaders(ClassLoader classLoader) { return new ClassLoader[] { classLoader, defaultClassLoader, // 当前哨程的高下文类加载器 Thread.currentThread().getContextClassLoader(), // MyBatis类的类加载器 getClass().getClassLoader(), // 系统类加载器 systemClassLoader };}
由上面的代码可以看出,5种类加载器分别为:
自定义类加载器,可能为 null;默认类加载器,可能为 null;线程高下文类加载器;MyBatis类加载器;系统类加载器;