《Mybatis》第一篇 系统读取Mybatis-config.xml核心配置文件流程

一.前言

本人是一个java后端开发新手,由于近期的项目中添加了mybatis技术,虽然技术会使用,但是不太了解配置文件是如何加载读取到的,所以按照自己的理解整理出一份说明。
<如有不足之处,麻烦指出>

二.底层代码解析

在这里插入图片描述


图上时序图步骤解析说明<附上代码块,序号和图中序号对应>:
1.一般代码中加载配置只需要一行代码搞定,如下

   //代码中从类路径中加载核心配置文件resource = "mybatis-comfig.xml "
   InputStream inputStream = Resources.getResourceAsStream(resource);

2.重载的方法中创建一个类加载器ClassLoader实例对象loader,并调用类加载器包装类classLoaderWrapper的方法
getResourceAsStream(resource, loader)

/*
   * 以流对象的形式返回类路径上的资源
   *
   * @param resource The resource to find
   * @return The resource
   * @throws java.io.IOException If the resource cannot be found or read
   */
  public static InputStream getResourceAsStream(String resource) throws IOException {
    return getResourceAsStream(null, resource); //调用Resources内部重载方法,参数为路径名
  }

/*
   * 以流对象的形式返回类路径上的资源
   *
   * @param loader   The classloader used to fetch the resource
   * @param resource The resource to find
   * @return The resource
   * @throws java.io.IOException If the resource cannot be found or read
   */
  public static InputStream getResourceAsStream(ClassLoader loader, String resource) throws IOException {
    InputStream in = classLoaderWrapper.getResourceAsStream(resource, loader); //返回IO流对象InputStream
    if (in == null) throw new IOException("Could not find resource " + resource);
    return in;
  }

3 && 4.classLoaderWrapper来加载器包装类的getResourceAsStream(resource, loader)方法

/*
   * Get a resource from the classpath, starting with a specific class loader
   *
   * @param resource    - the resource to find
   * @param classLoader - the first class loader to try
   * @return the stream or null
   */
  public InputStream getResourceAsStream(String resource, ClassLoader classLoader) {
    //getClassLoaders(classLoader)为获取所有类型的类加载器
    return getResourceAsStream(resource, getClassLoaders(classLoader)); 
  }

//4.自调getClassLoaders(classLoader)方法,返回一个类加载器数组,内部包含5类加载器
ClassLoader[] getClassLoaders(ClassLoader classLoader) {
        return new ClassLoader[]{  
            classLoader,   //由参数指定的默认类加载器
            defaultClassLoader, //系统指定的类加载器
            Thread.currentThread().getContextClassLoader(), //当前线程绑定的类加载器
            getClass().getClassLoader(), //加载当前类所使用的类加载器
            systemClassLoader}; //系统类加载器
      }

5 && 6.循环使用每一个类加载器去加载配置路径资源,每个类最多加载两次,第一次直接以配置文件名作为路径加载,如果没有加载到资源,则拼接一个"/"形成一个新的路径名再次加载

 /*
   * Try to get a resource from a group of classloaders
   * 尝试循环使用每一个类加载器去加载资源
   *
   * @param resource    - the resource to get
   * @param classLoader - the classloaders to examine
   * @return the resource or null
   */
  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;
      }
    }
    //两次都没加载到,返回null,下一个类加载器classLoader继续重复上面操作
    return null;
  }

//6.每个类加载器classLoader去调用方法getResourceAsStream(resource)方法,内部自调方法getResource(name)
   /**
     * Returns an input stream for reading the specified resource.
     * 返回用于读取指定资源的输入流
     * <p> The search order is described in the documentation for {@link
     * #getResource(String)}.  </p>
     *
     * @param  name
     *         The resource name
     *
     * @return  An input stream for reading the resource, or <tt>null</tt>
     *          if the resource could not be found
     *
     * @since  1.1
     */
    public InputStream getResourceAsStream(String name) {
        URL url = getResource(name); //自调
        try {
            return url != null ? url.openStream() : null;
        } catch (IOException e) {
            return null;
        }
    }
  
 //内部自调方法getResource(name)
   /**
     * Finds the resource with the given name.  A resource is some data
     * (images, audio, text, etc) that can be accessed by class code in a way
     * 查找具有给定名称的资源。资源是一些数据(图像、音频、文本等),可以通过类代码以某种方式访问
     * that is independent of the location of the code.
     *
     * <p> The name of a resource is a '<tt>/</tt>'-separated path name that
     * identifies the resource.
     *
     * <p> This method will first search the parent class loader for the
     * resource; if the parent is <tt>null</tt> the path of the class loader
     * built-in to the virtual machine is searched.  That failing, this method
     * will invoke {@link #findResource(String)} to find the resource.  </p>
     *
     * @param  name
     *         The resource name
     *
     * @return  A <tt>URL</tt> object for reading the resource, or
     *          <tt>null</tt> if the resource could not be found or the invoker
     *          doesn't have adequate  privileges to get the resource.
     *
     * @since  1.1
     */
    public URL getResource(String name) {
        URL url;
        if (parent != null) {
            //parent 为此类ClassLoader类加载器中初始化委托的父类装入器
            //private final ClassLoader parent;
            url = parent.getResource(name);  
        } else {
            url = getBootstrapResource(name);   //自调getBootstrapClassPath方法返回一个URLClassPath实例对象
        }
        if (url == null) {
            url = findResource(name);
        }
        return url;
    }

7 && 8 && 9.自调getBootstrapClassPath方法返回一个URLClassPath实例对象

    /**
    * Find resources from the VM's built-in classloader.
    * 从VM的内置类加载器中查找资源。
    */
   private static URL getBootstrapResource(String name) {
       URLClassPath ucp = getBootstrapClassPath();  
       //8.调用URLClassPath类中getResource(name)返回Resource实例对象
       Resource res = ucp.getResource(name); 
       return res != null ? res.getURL() : null;
   }

   //A:返回用于查找系统资源的URLClassPath。
   static URLClassPath getBootstrapClassPath() {
       return sun.misc.Launcher.getBootstrapClassPath();
   }

10.classLoaderWrapper将最终获取的IO流InputStream对象加载的配置资源返还给Resource

/*
   * 以流对象的形式返回类路径上的资源
   *
   * @param loader   The classloader used to fetch the resource
   * @param resource The resource to find
   * @return The resource
   * @throws java.io.IOException If the resource cannot be found or read
   */
  public static InputStream getResourceAsStream(ClassLoader loader, String resource) throws IOException {
    InputStream in = classLoaderWrapper.getResourceAsStream(resource, loader); //返回IO流对象InputStream
    if (in == null) throw new IOException("Could not find resource " + resource);
    return in;
  }
    //获取到的inputStream流对象返回Resource<逆向反推到最开始的那段代码>
    //代码中从类路径中加载核心配置文件mybatis-comfig.xml 
    InputStream inputStream = Resources.getResourceAsStream(resource);
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 可以,您可以将mybatis-config.xml文件复制到IDEA项目的任何目录中,然后通过代码中的配置加载该文件。在配置文件中指定的属性和设置将被应用于您的MyBatis应用程序。要加载配置文件,可以使用MyBatis的SqlSessionFactoryBuilder类的build()方法,该方法接受mybatis-config.xml文件作为参数,将其解析并构建SqlSessionFactory对象。 ### 回答2: 是的,mybatis-config.xml可以直接复制到IDEA的项目代码中使用。MyBatis是一种Java持久化框架,用于将数据库操作集成到Java应用程序中。mybatis-config.xmlMyBatis配置文件,用于配置MyBatis的各项设置和属性。 在IDEA中使用MyBatis时,我们需要在项目中添加mybatis-config.xml文件,并将其放置在正确的位置。一般而言,我们可以将mybatis-config.xml放在src/main/resources目录下。 将mybatis-config.xml复制到IDEA的代码中是很简单的。首先,我们需要创建一个resources文件夹,然后将mybatis-config.xml文件复制到该文件夹下。接下来,IDEA会自动将该文件夹标记为资源文件夹,确保该文件夹中的文件可以在项目中直接访问。 复制完毕后,我们可以在代码中使用MyBatis读取mybatis-config.xml文件,并根据其中的配置信息来进行数据库操作。通常情况下,我们可以使用如下代码加载mybatis-config.xml文件: ```java String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); ``` 以上代码会读取mybatis-config.xml文件并创建一个SqlSessionFactory对象,用于创建和管理数据库会话。 总而言之,将mybatis-config.xml复制到IDEA的代码中是很容易的,并且可以使我们在使用MyBatis时轻松地配置和管理数据库操作。 ### 回答3: 是的,mybatis-config.xml文件可以直接复制到IDEA的代码中使用。MyBatis是一个基于Java的持久层框架,通过mybatis-config.xml文件配置MyBatis的运行方式和一些基本的参数设置。在IDEA中,我们可以将mybatis-config.xml文件直接复制到项目的相应目录下,然后在代码中引用该文件。 首先,我们需要在项目的资源文件夹下创建一个名为"mybatis"的文件夹,然后将mybatis-config.xml文件复制到该文件夹中。接着,我们可以在代码中通过以下方式引用mybatis-config.xml文件: ```java String resource = "mybatis/mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); ``` 以上代码中,通过`Resources.getResourceAsStream(resource)`方法获取mybatis-config.xml文件的输入流,然后通过`SqlSessionFactoryBuilder().build(inputStream)`方法将输入流转换为SqlSessionFactory对象,从而进行数据库操作。 需要注意的是,在使用IDEA时,我们需要确保mybatis-config.xml文件的路径和上述代码中的路径一致。此外,如果mybatis-config.xml文件中有其他依赖的配置文件,也需要将它们复制到相应的位置。 总而言之,mybatis-config.xml文件可以直接复制到IDEA的代码中,并通过代码中的相应方法引用和使用。这样我们就可以方便地在IDEA中配置和运行MyBatis框架,进行数据库操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

搬砖界的小白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值