本章主要描述 MyBatis 资源加载模块中的 ClassLoaderWrapper 类和 Java 加载配置文件的三种方式。

ClassLoaderWrapper

上一章的案例,使用 org.apache.ibatis.io.Resources#getResourceAsStream(java.lang.String) 方法加载 MyBatis 的配置文件。Resources 是一个提供了多个静态方法的工具类,内部封装了 ClassLoaderWrapper 类的静态字段,Resources 提供的方法都是在 ClassLoaderWrapper 对象中实现的。

ClassLoaderWrapper 主要提供了三类方法:classForName() 方法、getResourceAsStream() 方法、getResourceAsURL() 方法,这三个方法都有多个重载。这里以 getResourceAsStream() 方法为例进行介绍。

org.apache.ibatis.io.ClassLoaderWrapper#getResourceAsStream(java.lang.String, java.lang.ClassLoader[]) 方法源码如下:

public InputStream getResourceAsStream(String resource, ClassLoader classLoader) {
return getResourceAsStream(resource, getClassLoaders(classLoader));
} // 该方法返回ClassLoader[]数组,该数组指明了类加载器的使用顺序
ClassLoader[] getClassLoaders(ClassLoader classLoader) {
return new ClassLoader[]{
classLoader,// 参数指定的类加载器
defaultClassLoader,// 类中指定的默认类加载器
Thread.currentThread().getContextClassLoader(),// 当前线程绑定的类加载器
getClass().getClassLoader(),// 加载当前类所使用的类加载器
systemClassLoader};// 系统类加载器
} InputStream getResourceAsStream(String resource, ClassLoader[] classLoader) {
// 遍历ClassLoader数组
for (ClassLoader cl : classLoader) {
if (null != cl) {
// 调用ClassLoader.getResourceAsStream方法加载指定的资源
InputStream returnValue = cl.getResourceAsStream(resource);
// 尝试以“/”开头,再次查找
if (null == returnValue) {
returnValue = cl.getResourceAsStream("/" + resource);
}
if (null != returnValue) {
return returnValue;
}
}
}
return null;
}

getResourceAsStream() 方法本质还是使用 Java 类加载器的方式加载配置文件。

Java 加载配置文件的三种方式

项目结构是普通的 Java 项目,非 Maven 项目。如果是 Maven 项目,配置文件会放在 resources 目录下,打成 jar 文件后,配置文件会存在 classpath 根目录下,所以一般使用类加载器的方式加载配置文件。

以下内容转载自:《Java中加载配置文件的三种方式》

配置文件放置位置如下图所示:

1. 通过文件路径加载

/**
* 通过文件路径加载
*
* @throws Exception
*/
public static void loadByFilePath() {
InputStream in = null;
try {
in = new FileInputStream(
"E:/project/test/src/com/resource/config.properties");
Properties props = new Properties();
props.load(in);
String host = props.getProperty("host");
System.out.println(host);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

FileInputStream 中的参数是配置文件的真实路径。

2. 通过的 Class 的 getResourceAsStream 进行加载

采用相对路径的方式:

/**
* 通过的 Class 的 getResourceAsStream 进行加载,相对路径
*/
public static void loadByClassRelativePath() {
InputStream in = null;
try {
in = ResourceLoader.class.getResourceAsStream("config.properties");
Properties props = new Properties();
props.load(in);
String host = props.getProperty("host");
System.out.println(host);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

采用绝对路径的方式:

/**
* 通过的 Class 的 getResourceAsStream 进行加载,绝对路径
*/
public static void loadByClassAbsolutePath() {
InputStream in = null;
try {
in = ResourceLoader.class.getResourceAsStream("/com/resource/config.properties");
Properties props = new Properties();
props.load(in);
String host = props.getProperty("host");
System.out.println(host);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

3. 通过类加载器的方式进行加载

/**
* 通过类加载器的方式进行加载
*/
public static void loadByClassLoader() {
InputStream in = null;
try {
// ClassLoader会在classpath所在的根目录下查找文件
// 注意:目录最前面不要加 /
in = ResourceLoader.class.getClassLoader().getResourceAsStream("com/resource/config.properties");
Properties props = new Properties();
props.load(in);
String host = props.getProperty("host");
System.out.println(host);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

MyBatis 源码篇

MyBatis 源码篇-资源加载的更多相关文章

  1. Mybatis源码解析(二) —— 加载 Configuration

    Mybatis源码解析(二) -- 加载 Configuration    正如上文所看到的 Configuration 对象保存了所有Mybatis的配置信息,也就是说mybatis-config. ...

  2. mybatis源码分析--如何加载配置及初始化

    简介 Mybatis 是一个持久层框架,它对 JDBC 进行了高级封装,使我们的代码中不会出现任何的 JDBC 代码,另外,它还通过 xml 或注解的方式将 sql 从 DAO/Repository ...

  3. Mybatis源码解读-配置加载和Mapper的生成

    问题 Mybatis四大对象的创建顺序? Mybatis插件的执行顺序? 工程创建 环境:Mybatis(3.5.9) mybatis-demo,参考官方文档 简单示例 这里只放出main方法的示例, ...

  4. springboot集成mybatis源码分析-启动加载mybatis过程(二)

    1.springboot项目最核心的就是自动加载配置,该功能则依赖的是一个注解@SpringBootApplication中的@EnableAutoConfiguration 2.EnableAuto ...

  5. MyBatis 源码篇-MyBatis-Spring 剖析

    本章通过分析 mybatis-spring-x.x.x.jar Jar 包中的源码,了解 MyBatis 是如何与 Spring 进行集成的. Spring 配置文件 MyBatis 与 Spring ...

  6. MyBatis 源码篇-Transaction

    本章简单介绍一下 MyBatis 的事务模块,这块内容比较简单,主要为后面介绍 mybatis-spring-1.**.jar(MyBatis 与 Spring 集成)中的事务模块做准备. 类图结构 ...

  7. MyBatis 源码篇-DataSource

    本章介绍 MyBatis 提供的数据源模块,为后面与 Spring 集成做铺垫,从以下三点出发: 描述 MyBatis 数据源模块的类图结构: MyBatis 是如何集成第三方数据源组件的: Pool ...

  8. MyBatis 源码篇-插件模块

    本章主要描述 MyBatis 插件模块的原理,从以下两点出发: MyBatis 是如何加载插件配置的? MyBatis 是如何实现用户使用自定义拦截器对 SQL 语句执行过程中的某一点进行拦截的? 示 ...

  9. MyBatis 源码篇-日志模块2

    上一章的案例,配置日志级别为 debug,执行一个简单的查询操作,会将 JDBC 操作打印出来.本章通过 MyBatis 日志部分源码分析它是如何实现日志打印的. 在 MyBatis 的日志模块中有一 ...

随机推荐

  1. vue后台_实战篇

    一.一些常用组件效果的实现 1)面包屑导航 主要是使用$route.mathed:一个数组,包含当前路由的所有嵌套路径片段的路由记录 .路由记录就是 routes 配置数组中的对象副本 (还有在 ch ...

  2. Python语法 - yield表达式(类似 m = yield i )

      yield是个表达式而不仅仅是个语句,所以可以使用x = yield r 这样的语法, yield表达式可以接收send()发出的参数,yield表达式是跟send方法一起配合使用   send方 ...

  3. Apache Flink - 命令

    $flink命令位置 命令 选项 jar包位置 \ --input 输入文件位置 --out 输出文件位置 ./bin/flink run ./examples/batch/WordCount.jar ...

  4. DataTable 转换为List

           注意table 列的参数类型,若不为string 需要详细声明 如 typeof(Int32)          public static IList<T> Convert ...

  5. 问题MySQL Error (2013): Lost connection to MySQL server at waiting for initial communication packet

    错误说明: SQL Error (2013): Lost connection to MySQL server at 'waiting for initial communication packet ...

  6. 组件基础之动态tab组件

    <template> <div id="demo31"> <p>-----------------组件基础之动态tab组件一---------- ...

  7. Tomca的启动与关闭

    点击startup.bat启动,遇到一闪而过的问题,可能尚未配置JAVA_HOME 8080端口被占用导致启动失败 关闭Tomcat的三种方式 * 点击x (不推荐) * 双击shutdown.bat ...

  8. 014-操作系统下验证下载文件的 MD5/SHA1/SHA256

    一.mac 1.md5 openssl md5 /path/to/file 新的macOS默认支持:md5 filename 2.sha256 openssl dgst -sha256 /path/t ...

  9. 比特币区块的hash算法

    Block hashing algorithm Bitcoin mining uses the hashcash proof of work function; the hashcash algori ...

  10. iOS 11适配

    1.http://www.cocoachina.com/ios/20170915/20580.html   简书App适配iOS 11   2.http://www.jianshu.com/p/efb ...