本章主要描述 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. Leetcode题目543:二叉树的直径(简单)

    题目描述: 给定一棵二叉树,你需要计算它的直径长度.一棵二叉树的直径长度是任意两个结点路径长度中的最大值.这条路径可能穿过根结点. 示例 :给定二叉树 1 / \ 2 3 / \ 4 5 返回 3, ...

  2. DQL:查询表中数据

    1. 基础查询 (1) 查询整表 SELECT * FROM 表名; -- 不推荐使用"*",不方便阅读 (2) 选择性查询 SELECT 列名,列名,列名 FROM 表名; (3 ...

  3. Mysql -- 设置指定配置文件启动

    mysqld --defaults-file=/etc/my.cnf --user=root

  4. dnspy使用技巧

    打开dnspy,调试–>附加到进程–>选择相应的进程ID–>附加(支持同时附加多个进程) 调试–>窗口–>模块–>搜索要调试的程序集–>双击(这一步很重要, ...

  5. OS X以及iOS中与硬件环境相关的预定义宏

    由于现在ARM处理器的飞速发展,从Apple A4到现在的Apple A7,从32位到64位,每一代处理器几乎都增加了不少特性,从而在架构上也有所不同.比如Apple A6引入了ARMv7S架构,增加 ...

  6. 下了个pkg包的jenkins,的使用方法

    三.如何启动Jenkins1.最简单的方法是双击Jenkins的pkg包,一步一步点同意,默认8080端口2.使用命令行启动打开terminal,进入到war包所在目录,执行命令: java -jar ...

  7. 将springboot安装成windows服务启动。

    下载Windows Service Wrapper 本文下载了winsw-2.3.0-bin.exe. 新建一个目录aiplatformService 在目录里面新建一个aiplatformServi ...

  8. hadoop 2.8.5安装步骤

    1.创建hadoop用户,作为haoop的运行用户 2.配置JAVA_HOME环境变量,修改/etc/profile export JAVA_HOME=/usr/java/jdk1.8.0_51 ex ...

  9. layoutSubviews在以下情况下会被调用

    1.init初始化不会触发layoutSubviews2.addSubview会触发layoutSubviews3.设置view的Frame会触发layoutSubviews,当然前提是frame的值 ...

  10. Linux学习笔记之系统中的分区和文件系统

    转自 http://blog.csdn.net/hanxuehen/article/details/8229472