前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Mabatis 源码探究(2)Java 获取mybatis-config.xml的输入流 inputStream对象

Mabatis 源码探究(2)Java 获取mybatis-config.xml的输入流 inputStream对象

作者头像
宁在春
发布2022-10-31 14:38:15
2950
发布2022-10-31 14:38:15
举报
文章被收录于专栏:关于Java学习@宁在春

关于Mybatis源码探究的专栏。 其我的专业是软件技术这个方向的,mybatis 许久以前就学了,但是心里一直存在一些疑惑。也上网查了,看过各种大佬的博客,对 于Mybatis的理解始终感觉不足。最后还是决定要来肝它。 文字功底一般,请谅解。 若有不足,还望能够指正。 喜欢一句话: “八小时以内谋生存,八小时以外谋发展”。

---- 趁着还没有毕业,再看看学校的夜晚,学校的风景。

Java 获取mybatis-config.xml的输入流

获得加载核心配置文件的inputStream流

1)Resources.getResourceAsStream(String resource) 方法

这是我们都写过的一段代码,大家都知道,里面就是一个千层饼哈。

代码语言:javascript
复制
String resource="mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);

null 传的是空的类加载器,这里传过去空,但是在后面能够获得一些其他的类加载器。

代码语言:javascript
复制
public static InputStream getResourceAsStream(String resource) throws IOException {
  return getResourceAsStream(null, resource);
}
2)getResourceAsStream(null, resource); 方法

将类路径上的资源作为 输入流对象 返回

先将源码贴出来,下面再讲。

代码语言:javascript
复制
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);
  }
  return in;
}

我们在这段代码中,有看到InputStream对象的获得和返回,证明这classLoaderWrapper.getResourceAsStream(resource, loader); 个地方就是新建 InputStream 的地方,我们可以从这里入手,继续往下。

先看classLoaderWrapper 是怎么来的,要干什么事情

代码语言:javascript
复制
private static ClassLoaderWrapper classLoaderWrapper = new ClassLoaderWrapper();

这里用到的classLoaderWrapper 我搜到的解释如下:

  • 在MyBatis的IO包中封装了ClassLoader以及读取资源文件相关的API。
  • 在ClassLoaderWrapper是一个ClassLoader的包装器,其中包含了多个ClassLoader对象。 通过调整多个类加载器的使用顺序。使用ClassLoaderWrapper就如同使用ClassLoader对象,ClassLoaderWrapper 会按照指定的顺序依次检测其中封装的ClassLoader对象,并从中选取第一个可用的ClassLoader完成相关功能。 ClassLoaderWrapper中定义了两个字段,分别记录了系统指定的默认加载器(defaultClassLoader)和系统加载器(systemClassLoader)
  • ClassLoaderWrapper的主要功能分为三类: getResourceAsURL() getResourceAsStream() classFormName()
  • 原文链接:https://blog.csdn.net/xl3379307903/article/details/80994509
3) classLoaderWrapper.getResourceAsStream(resource, loader);

从类路径中获取资源,从特定的类加载器开始

参数解释: resource——要查找的资源 classLoader – 第一个要尝试的类加载器

代码语言:javascript
复制
  public InputStream getResourceAsStream(String resource, ClassLoader classLoader) {
    return getResourceAsStream(resource, getClassLoaders(classLoader));
  }

我们可以看到它又接着去调用了他的重载函数,但是我们在去看之前,先看看第二个参数是什么东西吧,不然会接着搞不明白。

**getClassLoaders(classLoader)**牵扯到的源码是这样的:

==注意:==这个方法返回是不会存在空值的,叠底的都还有系统类加载器勒

代码语言:javascript
复制
// 我们传过来的参数是null,但是我们返回的这个ClassLoader[] 数组,是肯定有值的。
ClassLoader[] getClassLoaders(ClassLoader classLoader) {
    return new ClassLoader[]{
        classLoader, /** 此处是null ,我们传过来的*/ 
        defaultClassLoader,  /**此处也是null */ 
        Thread.currentThread().getContextClassLoader(),/**使用当前线程的ClassLoader */
        getClass().getClassLoader(),/**使用当前类的ClassLoader */
        systemClassLoader};/**使用系统ClassLoader,即系统的入口点所使用的ClassLoader。 */
  }

我们返回接着往下看啊

4)getResourceAsStream(resource, getClassLoaders(classLoader));

这个方法的作用就是尝试从一组类加载器中获取资源 获取到了就会返回一个 InputStream 输入流对象给我们。

代码语言:javascript
复制
InputStream getResourceAsStream(String resource, ClassLoader[] classLoader) {
  for (ClassLoader cl : classLoader) {
    if (null != cl) {
      // try to find the resource as passed
      InputStream returnValue = cl.getResourceAsStream(resource);

      // now, some class loaders want this leading "/", so we'll add it and try again if we didn't find the resource
      if (null == returnValue) {
        returnValue = cl.getResourceAsStream("/" + resource);
      }

      if (null != returnValue) {
        return returnValue;
      }
    }
  }
  return null;
}

下面还接着嵌套了两个方法,实际作用就是找到文件所在的绝对地址,获取里面的内容。

5)cl.getResourceAsStream(resource);
代码语言:javascript
复制
    public InputStream getResourceAsStream(String name) {
        Objects.requireNonNull(name);
        URL url = getResource(name);
        try {
            return url != null ? url.openStream() : null;
        } catch (IOException e) {
            return null;
        }
    }

我debug 时候的图,给大家看一下吧。 可以看到在这里,

在这里插入图片描述
在这里插入图片描述

url.openStream();打开到此URL的连接并返回一个InputStream以从该连接读取。没有什么可看的。

牵扯到的小知识点:

检查指定的对象引用不为null 。

代码语言:javascript
复制
 Objects.requireNonNull(name);

此方法主要用于在方法和构造函数中进行参数验证,如下所示:

代码语言:javascript
复制
public Foo(Bar bar) {
    this.bar = Objects.requireNonNull(bar);
}

自言自语

未来还很远,记得给自己加油。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-06-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Java 获取mybatis-config.xml的输入流
  • 获得加载核心配置文件的inputStream流
  • 牵扯到的小知识点:
    • 自言自语
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档