前面两篇博客Mybatis接口编程原理分析(一)Mybatis接口编程原理分析(二)我们介绍了MapperProxyFactory、MapperProxy和MapperMethod的操作及源码分析,接下来我们介绍MapperRegistry

MapperRegistry:它是用来注册Mapper接口和获取登出代理类实例的工具类,它通过getMapper函数获得代理类和addMapper函数来注册代理类,

源码如下:

//这个类通过名字就可以看出 是用来注册Mapper接口与获取生成代理类实例的工具类
public class MapperRegistry {

  //全局配置文件对象
  private final Configuration config;

  //一个HashMap Key是mapper的类型对象, Value是MapperProxyFactory对象
  //这个MapperProxyFactory是创建Mapper代理对象的工厂
  private final Map<Class<?>, MapperProxyFactory<?>> knownMappers = new HashMap<Class<?>, MapperProxyFactory<?>>();

  public MapperRegistry(Configuration config) {
    this.config = config;
  }
   //获取生成的代理对象
  @SuppressWarnings("unchecked")
  public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
	//通过Mapper的接口类型 去Map当中查找 如果为空就抛异常
    final MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) knownMappers.get(type);
    if (mapperProxyFactory == null) {
      throw new BindingException("Type " + type + " is not known to the MapperRegistry.");
    }
    try {
	  //否则创建一个当前接口的代理对象 并且传入sqlSession
      return mapperProxyFactory.newInstance(sqlSession);
    } catch (Exception e) {
      throw new BindingException("Error getting mapper instance. Cause: " + e, e);
    }
  }

  public <T> boolean hasMapper(Class<T> type) {
    return knownMappers.containsKey(type);
  }
  //注册Mapper接口
  public <T> void addMapper(Class<T> type) {
    if (type.isInterface()) {
      if (hasMapper(type)) {
        throw new BindingException("Type " + type + " is already known to the MapperRegistry.");
      }
      boolean loadCompleted = false;
      try {
        knownMappers.put(type, new MapperProxyFactory<T>(type));
        // It's important that the type is added before the parser is run
        // otherwise the binding may automatically be attempted by the
        // mapper parser. If the type is already known, it won't try.
        MapperAnnotationBuilder parser = new MapperAnnotationBuilder(config, type);
        parser.parse();
        loadCompleted = true;
      } finally {
        if (!loadCompleted) {
          knownMappers.remove(type);
        }
      }
    }
  }

  /**
   * @since 3.2.2
   */
  public Collection<Class<?>> getMappers() {
    return Collections.unmodifiableCollection(knownMappers.keySet());
  }

  /**
   * @since 3.2.2
   */
  //注册Mapper接口
  public void addMappers(String packageName, Class<?> superType) {
    ResolverUtil<Class<?>> resolverUtil = new ResolverUtil<Class<?>>();
    resolverUtil.find(new ResolverUtil.IsA(superType), packageName);
    Set<Class<? extends Class<?>>> mapperSet = resolverUtil.getClasses();
    for (Class<?> mapperClass : mapperSet) {
      addMapper(mapperClass);
    }
  }

  /**
   * @since 3.2.2
   */
  //通过包名扫描下面所有接口
  public void addMappers(String packageName) {
    addMappers(packageName, Object.class);
  }

}

在DefaultSqlSession中通过getMapper函数从Configuration中获取代理类:

 @Override
  public <T> T getMapper(Class<T> type) {
    return configuration.<T>getMapper(type, this);
  }

在Configuration类中通过getMapper从MapperRegistry来获取代理类

public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
    return mapperRegistry.getMapper(type, sqlSession);
  }

这样就完成了mybatis接口编程的构造和调用的全部过程。

Mybatis接口编程原理分析(三)的更多相关文章

  1. Mybatis接口编程原理分析(二)

    在上一篇博客中 Mybatis接口编程原理分析(一)中我们介绍了MapperProxyFactory和MapperProxy,接下来我们要介绍的是MapperMethod MapperMethod:它 ...

  2. Mybatis接口编程原理分析(一)

    Mybatis接口编程示例 (1)首先定义接口编程需要的接口及其方法 public interface IUserMapper { public User getById(int id);//接口方法 ...

  3. MyBatis整合Spring原理分析

    目录 MyBatis整合Spring原理分析 MapperScan的秘密 简单总结 假如不结合Spring框架,我们使用MyBatis时的一个典型使用方式如下: public class UserDa ...

  4. MyBatis的深入原理分析之1-架构设计以及实例分析

    MyBatis是目前非常流行的ORM框架,它的功能很强大,然而其实现却比较简单.优雅.本文主要讲述MyBatis的架构设计思路,并且讨论MyBatis的几个核心部件,然后结合一个select查询实例, ...

  5. Linux下Golang Socket编程原理分析与代码实现

    在POSIX标准推出后,socket在各大主流OS平台上都得到了很好的支持.而Golang是自带Runtime的跨平台编程语言,Go中提供给开发者的Socket API是建立在操作系统原生Socket ...

  6. MyBatis框架及原理分析

    MyBatis 是支持定制化 SQL.存储过程以及高级映射的优秀的持久层框架,其主要就完成2件事情: 封装JDBC操作 利用反射打通Java类与SQL语句之间的相互转换 MyBatis的主要设计目的就 ...

  7. Mybatis插件原理分析(三)分页插件

    在Mybatis中插件最经常使用的是作为分页插件,接下来我们通过实现Interceptor来完成一个分页插件. 虽然Mybatis也提供了分页操作,通过在sqlSession的接口函数中设置RowBo ...

  8. mybatis(一、原理,一对多,多对一查询)

    MyBatis框架及原理分析 MyBatis 是支持定制化 SQL.存储过程以及高级映射的优秀的持久层框架,其主要就完成2件事情: 封装JDBC操作 利用反射打通Java类与SQL语句之间的相互转换 ...

  9. Spark原理分析目录

    1 Spark原理分析 -- RDD的Partitioner原理分析 2 Spark原理分析 -- RDD的shuffle简介 3 Spark原理分析 -- RDD的shuffle框架的实现概要分析 ...

随机推荐

  1. java 学习笔记2 面向对象(上)

    类和对象 类是某一批对象的抽象,可以把类理解成某种概念.对象是一个具体存在的实体.类和对象是面向对象的核心. 类定义的是多个实例的特征,类不是具体存在,实例才是具体存在. 定义类(class)的语法: ...

  2. gdb调试的基本使用

    GDB调试 启动程序准备调试 GDB yourpram 或者 先输入GDB 然后输入 file yourpram 然后使用run或者r命令开始程序的执行,也可以使用 run parameter将参数传 ...

  3. Node.js HTTP

    稳定性: 3 - 稳定 使用 HTTP 服务器或客户端功能必须调用 require('http'). Node 里的 HTTP 接口支持协议里原本比较难用的特性.特别是很大的或块编码的消息.这些接口不 ...

  4. MVC和MTV模式

    著名的MVC模式:所谓MVC就是把web应用分为模型(M),控制器(C),视图(V)三层:他们之间以一种插件似的,松耦合的方式连接在一起. 模型负责业务对象与数据库的对象(ORM),视图负责与用户的交 ...

  5. Java语言程序设计-助教篇

    1. 给第一次上课(软件工程)的老师与助教 现代软件工程讲义 0 课程概述 给学生:看里面的第0个作业要求 2. 助教心得 美国视界(1):第一流的本科课堂该是什么样?(看里面的助教部分) 助教工作看 ...

  6. Leetcode难度表及解题汇总

    Leetcode难度表及解题汇总 参考网上一份题目难度表,以及本人的解题. Id Question Difficulty Frequency Data Structures Algorithms Bl ...

  7. 亲密接触Redis-第二天(Redis Sentinel)

    简介 经过上次轻松搭建了一个Redis的环境并用Java代码调通后,这次我们要来看看Redis的一些坑以及Redis2.8以后带来的一个新的特性即支持高可用特性功能的Sentinel(哨兵). Red ...

  8. Android系统的安全设计与架构

    Android系统的安全设计与架构 一.安全策略 1.Android 的总体架构由5个主要层次上的组件构成,这5层是:Android应用层. Android框架层.Dalvik虚拟机层.用户空间原生代 ...

  9. 2apt-get命令,deb包安装,源码安装

    1 安装卸载软件 更新源服务器列表 sudovi /etc/apt/sources.list 更新完服务器列表后需要更新下源 sudoapt-get update 更新源 sudoapt-get in ...

  10. Java基本语法-----java运算符的优先级与结合性

    这是本人以前的上学期间java 运算符这块知识的总结的,截图存到了word里,大家将就看下吧(不会用Markdown的表格 不然就在写一遍了 T T). [正在看本人博客的这位童鞋,我看你气度不凡,谈 ...