MyBatis 源码篇-资源加载
本章主要描述 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 源码篇-资源加载的更多相关文章
- Mybatis源码解析(二) —— 加载 Configuration
Mybatis源码解析(二) -- 加载 Configuration 正如上文所看到的 Configuration 对象保存了所有Mybatis的配置信息,也就是说mybatis-config. ...
- mybatis源码分析--如何加载配置及初始化
简介 Mybatis 是一个持久层框架,它对 JDBC 进行了高级封装,使我们的代码中不会出现任何的 JDBC 代码,另外,它还通过 xml 或注解的方式将 sql 从 DAO/Repository ...
- Mybatis源码解读-配置加载和Mapper的生成
问题 Mybatis四大对象的创建顺序? Mybatis插件的执行顺序? 工程创建 环境:Mybatis(3.5.9) mybatis-demo,参考官方文档 简单示例 这里只放出main方法的示例, ...
- springboot集成mybatis源码分析-启动加载mybatis过程(二)
1.springboot项目最核心的就是自动加载配置,该功能则依赖的是一个注解@SpringBootApplication中的@EnableAutoConfiguration 2.EnableAuto ...
- MyBatis 源码篇-MyBatis-Spring 剖析
本章通过分析 mybatis-spring-x.x.x.jar Jar 包中的源码,了解 MyBatis 是如何与 Spring 进行集成的. Spring 配置文件 MyBatis 与 Spring ...
- MyBatis 源码篇-Transaction
本章简单介绍一下 MyBatis 的事务模块,这块内容比较简单,主要为后面介绍 mybatis-spring-1.**.jar(MyBatis 与 Spring 集成)中的事务模块做准备. 类图结构 ...
- MyBatis 源码篇-DataSource
本章介绍 MyBatis 提供的数据源模块,为后面与 Spring 集成做铺垫,从以下三点出发: 描述 MyBatis 数据源模块的类图结构: MyBatis 是如何集成第三方数据源组件的: Pool ...
- MyBatis 源码篇-插件模块
本章主要描述 MyBatis 插件模块的原理,从以下两点出发: MyBatis 是如何加载插件配置的? MyBatis 是如何实现用户使用自定义拦截器对 SQL 语句执行过程中的某一点进行拦截的? 示 ...
- MyBatis 源码篇-日志模块2
上一章的案例,配置日志级别为 debug,执行一个简单的查询操作,会将 JDBC 操作打印出来.本章通过 MyBatis 日志部分源码分析它是如何实现日志打印的. 在 MyBatis 的日志模块中有一 ...
随机推荐
- Exception in thread "main" java.util.ConcurrentModificationException解决方案
我想判断一个集合里面有没有"world"这个元素,如果有,我就添加一个"javaee"元素, 当时的做法是: public class ListIterator ...
- pwn学习日记Day6 基础知识积累
知识杂项 ELF:在计算机科学中,是一种用于二进制文件.可执行文件.目标代码.共享库和核心转储格式文件. char fgets(char buf, int bufsize, FILE stream); ...
- Embedded based learning
简单整理了一些嵌入式底层需要接触的相关概念. # CPU CU. Control Unit. send need-clac-data -> ALU clac -> get resul ...
- kotlin标准委托之可观察属性
所谓可观察属性就是当属性变化时可以拦截其变化,实现观察属性值变化的委托函数是Delegates.observable.该函数接受二个参数,第一个是初始化值,第2个属性值变化事件的响应器.每次我们向属性 ...
- kotlin 泛型约束
fun <T:Comparable<T>> sort(list :List<T>){} 冒号之后指定的类型就是泛型参数的上界,对于泛型参数T,只允许使用Compar ...
- ubuntu tensorflow cpu faster-rcnn train data
(flappbird) luo@luo-All-Series:~/MyFile/tf-faster-rcnn_box$ (flappbird) luo@luo-All-Series:~/MyFile/ ...
- 通过route指令指定笔记本同时连接外网和内网
假如你的外网网关是:X.X.X.X 内网网关:192.168.1.1 则在命令窗口输入以下两条命令: route add 0.0.0.0 mask 0.0.0.0 X.X.X.X route add ...
- [System Design] Design a distributed key value caching system, like Memcached or Redis
https://www.interviewbit.com/problems/design-cache/ Features: This is the first part of any system d ...
- EPP状态码
服务器状态代码由您的域的注册表设置 EPP状态码 RDAP状态映射 这是什么意思? 你应该做点什么吗? addPeriod 加期 该宽限期是在域名初始注册后提供的.如果注册服务商在此期间删除了域名,则 ...
- 单例Bean注册表接口SingletonBeanRegistry
Github: SingletonBeanRegistry.java SingletonBeanRegistry package org.springframework.beans.factory.c ...