栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【mybatis源码解析】(三)MapperRegistry类解析

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【mybatis源码解析】(三)MapperRegistry类解析

系列文章目录

【mybatis源码解析】(一)mybatis执行流程以及实现原理
【mybatis源码解析】(二)详解mybatis中java动态代理模式的运用
【mybatis源码解析】(三)MapperRegistry类解析

文章目录

系列文章目录前言一、MapperRegistry是什么?二、MapperRegistry初始化


前言

前面两篇文章介绍了大体流程,这篇着重介绍跟MapperRegistry相关的类

一、MapperRegistry是什么?

MapperRegistry翻译过来就是映射器注册表
看看他的属性

config是存储了mybatis相关配置的类
knownMappers是一个以mpper接口类对象为key,MapperProxyFactory为值的map集合

构造函数需要传入配置对象

getMapper方法返回mapper的动态代理生成的对象

配置中是否拥有mapper

添加一个MapperFProxyFactory对象到map集合,初始化时候会调用

二、MapperRegistry初始化


在Configuration类中我们可以看到MapperRegistry的属性创建,说明在创建Configuration类时候就创建了MapperRegistry对象。
Configuration类在XMLConfigBuilder类中完成了创建
接下来看看的XMLConfigBuilder的parseConfiguration(XNode root)方法

有一个mapperElement(root.evalNode(“mappers”));方法,进去看看

  private void mapperElement(XNode parent) throws Exception {
    if (parent != null) {
      for (XNode child : parent.getChildren()) {
        if ("package".equals(child.getName())) {
          String mapperPackage = child.getStringAttribute("name");
          configuration.addMappers(mapperPackage);
        } else {
          String resource = child.getStringAttribute("resource");
          String url = child.getStringAttribute("url");
          String mapperClass = child.getStringAttribute("class");
          if (resource != null && url == null && mapperClass == null) {
            ErrorContext.instance().resource(resource);
            try(InputStream inputStream = Resources.getResourceAsStream(resource)) {
              XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, resource, configuration.getSqlFragments());
              mapperParser.parse();
            }
          } else if (resource == null && url != null && mapperClass == null) {
            ErrorContext.instance().resource(url);
            try(InputStream inputStream = Resources.getUrlAsStream(url)){
              XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, url, configuration.getSqlFragments());
              mapperParser.parse();
            }
          } else if (resource == null && url == null && mapperClass != null) {
            Class mapperInterface = Resources.classForName(mapperClass);
            configuration.addMapper(mapperInterface);
          } else {
            throw new BuilderException("A mapper element may only specify a url, resource or class, but not more than one.");
          }
        }
      }
    }
  }

处理方法总结来说就是解析xml配置,将mapper相关信息提出来,调用configuration.addMappers(mapperPackage),将mapper加入MapperRegistry的knownMappers属性
就是这个方法

  public  void addMapper(Class 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<>(type));//创建MapperProxyFactory工厂类放入
        // 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);//mapper其他配置解析生成
        parser.parse();
        loadCompleted = true;
      } finally {
        if (!loadCompleted) {
          knownMappers.remove(type);
        }
      }
    }
  }
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/785083.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号