`

Mybatis IO包源码分析

阅读更多
ClassLoaderWrapper 类是对 ClassLoader 的包装. 怎么理解了?看下这个方法就知道了.

ClassLoader[] getClassLoaders(ClassLoader classLoader) {
    return new ClassLoader[]{
        classLoader,
        defaultClassLoader,
        Thread.currentThread().getContextClassLoader(),
        getClass().getClassLoader(),
        systemClassLoader};
  }

实例化一个 Class.
Class<?> classForName(String name, ClassLoader[] classLoader) throws ClassNotFoundException {

    for (ClassLoader cl : classLoader) {

      if (null != cl) {

        try {

          Class<?> c = Class.forName(name, true, cl);

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

        } catch (ClassNotFoundException e) {
          // we'll ignore this until all classloaders fail to locate the class
        }

      }

    }

    throw new ClassNotFoundException("Cannot find class: " + name);

  }

查找资源.
URL getResourceAsURL(String resource, ClassLoader[] classLoader) {

    URL url;

    for (ClassLoader cl : classLoader) {

      if (null != cl) {

        // look for the resource as passed in...
        url = cl.getResource(resource);

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

        // "It's always in the last place I look for it!"
        // ... because only an idiot would keep looking for it after finding it, so stop looking already.
        if (null != url) {
          return url;
        }

      }

    }

    // didn't find it anywhere.
    return null;

  }

Resources 是 Mybatis 提供的用于读取资源文件的工具类,我们可以看到它仅仅是对 ClassLoaderWrapper 一层浅浅的封装.

VFS 是虚拟文件系统通用的 API.

VFS 提供了新增用户自定义 VFS 的功能.

看了下 VFS 的实现类,没发现啥重要的东西.

接下来的这个类比较重要. ResolverUtil.

一个测试接口,比如用于判断一个类是否是另一个类的父类,看某个类上是否存在某个注解等.
/**
   * A simple interface that specifies how to test classes to determine if they
   * are to be included in the results produced by the ResolverUtil.
   */
  public interface Test {
    /**
     * Will be called repeatedly with candidate classes. Must return True if a class
     * is to be included in the results, false otherwise.
     */
    boolean matches(Class<?> type);
  }

判断 parent 是否是 type 的父类.
public static class IsA implements Test {
    private Class<?> parent;

    /** Constructs an IsA test using the supplied Class as the parent class/interface. */
    public IsA(Class<?> parentType) {
      this.parent = parentType;
    }

    /** Returns true if type is assignable to the parent type supplied in the constructor. */
    @Override
    public boolean matches(Class<?> type) {
      return type != null && parent.isAssignableFrom(type);
    }

    @Override
    public String toString() {
      return "is assignable to " + parent.getSimpleName();
    }
  }

判断 type 上是否存在注解 annotation.
public static class AnnotatedWith implements Test {
    private Class<? extends Annotation> annotation;

    /** Constructs an AnnotatedWith test for the specified annotation type. */
    public AnnotatedWith(Class<? extends Annotation> annotation) {
      this.annotation = annotation;
    }

    /** Returns true if the type is annotated with the class provided to the constructor. */
    @Override
    public boolean matches(Class<?> type) {
      return type != null && type.isAnnotationPresent(annotation);
    }

    @Override
    public String toString() {
      return "annotated with @" + annotation.getSimpleName();
    }
  }

在 packageNames 下查找 parent 的实现类. 将查找到的结果放入 matches 集合.
public ResolverUtil<T> findImplementations(Class<?> parent, String... packageNames) {
    if (packageNames == null) {
      return this;
    }

    Test test = new IsA(parent);
    for (String pkg : packageNames) {
      find(test, pkg);
    }

    return this;
  }

在 packageNames 下查找被注解 annotation 修饰的类. 将查找到的结果放入 matches 集合.
public ResolverUtil<T> findAnnotated(Class<? extends Annotation> annotation, String... packageNames) {
    if (packageNames == null) {
      return this;
    }

    Test test = new AnnotatedWith(annotation);
    for (String pkg : packageNames) {
      find(test, pkg);
    }

    return this;
  }

递归查找.
public ResolverUtil<T> find(Test test, String packageName) {
    String path = getPackagePath(packageName);

    try {
      // 这里用到了 VFS,我们还是看下 VFS 的实现吧.
      List<String> children = VFS.getInstance().list(path);
      for (String child : children) {
        if (child.endsWith(".class")) {
          addIfMatching(test, child);
        }
      }
    } catch (IOException ioe) {
      log.error("Could not read package: " + packageName, ioe);
    }

    return this;
  }

再看下 VFS.

VFS 中定义了两个抽象方法,用于子类实现.
// 从 URL 中搜索和 forPath 匹配的路径.
protected abstract List<String> list(URL url, String forPath) throws IOException;
// 判断此 VFS 是否有效.
public abstract boolean isValid();

VFS 类定义好了获取 VFS 实例的逻辑. 优先使用用户自定义的 VFS,其次是系统实现的.
static VFS createVFS() {
      // Try the user implementations first, then the built-ins
      List<Class<? extends VFS>> impls = new ArrayList<>();
      impls.addAll(USER_IMPLEMENTATIONS);
      impls.addAll(Arrays.asList((Class<? extends VFS>[]) IMPLEMENTATIONS));

      // Try each implementation class until a valid one is found
      VFS vfs = null;
      for (int i = 0; vfs == null || !vfs.isValid(); i++) {
        Class<? extends VFS> impl = impls.get(i);
        try {
          vfs = impl.getDeclaredConstructor().newInstance();
          if (!vfs.isValid()) {
            if (log.isDebugEnabled()) {
              log.debug("VFS implementation " + impl.getName() +
                  " is not valid in this environment.");
            }
          }
        } catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
          log.error("Failed to instantiate " + impl, e);
          return null;
        }
      }

      if (log.isDebugEnabled()) {
        log.debug("Using VFS adapter " + vfs.getClass().getName());
      }

      return vfs;
    }

关于 DefaultVFS 是读取 Jar 文件. 详细的就不分析了.
0
1
分享到:
评论

相关推荐

    mybatis项目源码

    通过分析这些源码,初学者不仅可以理解MyBatis的基本工作流程,还能深入学习到Java编程、反射、AOP(面向切面编程)等相关知识。同时,这也有助于掌握实际项目中如何优雅地集成MyBatis,提升数据库操作的灵活性和...

    mybatis逆向工程源码及需要的jar

    首先,`mybatis逆向工程源码`是指MyBatis提供的工具或插件,用于分析数据库表结构并自动生成与之对应的Java代码。源码通常包括处理数据库连接、解析表信息、生成代码的逻辑。在源码中,我们可以看到如何通过JDBC连接...

    Mybatis源码分析

    Mybatis源码分析 Mybatis是一款流行的持久化框架,提供了强大的SQL映射和缓存机制。本文将对Mybatis的源码进行分析,探究其运行原理、缓存机制和设计模式。 Mybatis简介 Mybatis是一个第一类持久化框架,支持...

    Mybatis源码分析-上课笔记1

    本篇文章将深入分析MyBatis的核心概念和源码结构。 首先,我们来看一下MyBatis的主要组件: 1. **Configuration**:这是MyBatis的核心配置对象,它包含了全局配置信息,如数据源、事务管理器、Mappers等。...

    架构师之路分布式系列课程(SpringMybatisNettyRPC).7z

    │ mybatis源码分析10-1.mp4 │ mybatis源码分析10-2.mp4 │ mybatis源码分析11.mp4 │ mybatis源码分析12.mp4 │ mybatis源码分析13.mp4 │ mybatis源码分析14.mp4 │ mybatis源码分析15.mp4 │ mybatis源码...

    架构师之路分布式系列课程(SpringMybatisNettyRPC).zip

    │ mybatis源码分析10-1.mp4 │ mybatis源码分析10-2.mp4 │ mybatis源码分析11.mp4 │ mybatis源码分析12.mp4 │ mybatis源码分析13.mp4 │ mybatis源码分析14.mp4 │ mybatis源码分析15.mp4 │ mybatis源码...

    架构师之路分布式系列课程(SpringMybatisNettyRPC) - 副本 - 副本.zip

    │ mybatis源码分析10-1.mp4 │ mybatis源码分析10-2.mp4 │ mybatis源码分析11.mp4 │ mybatis源码分析12.mp4 │ mybatis源码分析13.mp4 │ mybatis源码分析14.mp4 │ mybatis源码分析15.mp4 │ mybatis源码...

    架构师之路分布式系列课程(SpringMybatisNettyRPC) - 副本.zip

    │ mybatis源码分析10-1.mp4 │ mybatis源码分析10-2.mp4 │ mybatis源码分析11.mp4 │ mybatis源码分析12.mp4 │ mybatis源码分析13.mp4 │ mybatis源码分析14.mp4 │ mybatis源码分析15.mp4 │ mybatis源码...

    架构师之路分布式系列课程(SpringMybatisNettyRPC).rar

    │ mybatis源码分析10-1.mp4 │ mybatis源码分析10-2.mp4 │ mybatis源码分析11.mp4 │ mybatis源码分析12.mp4 │ mybatis源码分析13.mp4 │ mybatis源码分析14.mp4 │ mybatis源码分析15.mp4 │ mybatis源码...

    zkxbatis:分析mybatis源码,实现自定义简化的mybatis复现

    源码分析 先看测试类: package uestc.zhangkx; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache....

    Springboot集成MyBatis自动生成代码工具源码

    在本文中,我们将深入探讨如何在Spring Boot项目中集成MyBatis并利用代码生成工具来提升开发效率。...通过分析这些源码,开发者可以更深入地理解Spring Boot与MyBatis的集成方式以及MBG的使用方法。

    MyBatis3开启二级缓存

    **五、源码分析** MyBatis的二级缓存实现主要涉及`Cache`接口及其实现类,如`PerpetualCache`,通过源码阅读,可以更深入理解缓存的工作流程,以及如何自定义缓存策略。 通过以上步骤,我们可以成功地在MyBatis3中...

    各种jar包的源码

    MyBatis源码分析有助于理解其动态SQL生成、事务管理、缓存实现等机制。特别是`SqlSession`和`Executor`接口,它们是MyBatis执行数据库操作的主要部分。 在给定的源码列表中,我们还看到了其他一些常用的Java库,如...

    Java笔记,从基础到进阶到源码分析,包括但不限于SSM,SpringBoot,SpringCloud,中间件.zip

    此外,源码分析部分可能会引导你深入理解这些框架和中间件的内部工作原理,例如Spring的IoC容器是如何运作的,或者MyBatis如何执行SQL查询。这将极大地提升你的编程技能和解决问题的能力。 总的来说,这个压缩包...

    java8集合源码分析-Awesome-Java:真棒-Java

    集合源码分析 Java 笔记 Java 语言相关的API,第三方库和计算机基础理论等知识的学习和整理 更多 : | | 目录 资源 详细目录 Java语言和JDK源码 Java语言的基础理论知识 并发编程 Java并发编程相关的内容,并发包源码...

    《Java十大经典案例》源码

    这些案例可能包括对象封装、继承、多态等面向对象编程的基本概念,以及异常处理、IO流、集合框架、线程同步等核心特性。通过实践,你可以深入了解Java语言的特性和使用场景。 2. **Spring框架案例**:Spring是企业...

    SpringMVC精品资源--基于SpringMVC,Spring,MyBatis实现的秒杀系统(参见慕课网,做了些.zip

    这个资源包中的"ahao5"可能是项目源码或文档的名称,具体内容未给出,但可以预期包含以下部分: - 源代码文件,包括SpringMVC的Controller、Service、DAO层的实现。 - 配置文件,如Spring的bean配置、MyBatis的...

    jdk-spring-sources:jdk,spring,mybatis

    3. **Spring MVC**:Spring MVC是Web应用的模型-视图-控制器架构,源码分析可以帮助我们理解请求处理流程,以及拦截器、视图解析等机制。 最后,Mybatis作为一款流行的持久层框架,其源码解析主要包括: 1. **SQL...

    log4j2+slf4j+spring4+mybatis的整合使用

    异步日志记录器采用了一种“无锁队列”机制,它能够减少上下文切换,并能够利用非阻塞IO提升性能。 log4j2还允许开发者扩展其功能,通过编写自定义的Appenders、Layouts、Filters以及其他组件,以满足特定日志记录...

    java8集合源码分析-java-demos:java-演示

    集合源码分析 java-demos other collect github project leetcode springCloud [Spring Cloud 从入门到实战] () [全网最详细的一篇SpringCloud总结] () [feign] () [Spring Security 真正的前后分离实现] () [Spring...

Global site tag (gtag.js) - Google Analytics