当前位置: 首页 > news >正文

03 Mybatis源码篇---XML配置之typeAliases 类型命名

看了几天源码,说实话看的挺懵逼的。只能写个demo一遍一遍的debugger追踪,看看MyBatis的运行原理到底是怎样的。下面大概看一下typeAliases类型别名的注册流程:
解析MyBatis配置文件configuration节点及子节点时,调用typeAliasesElement()来解析typeAliases属性来完成别名注册。

 /**
       * typeAliases 类型命名
       */
      typeAliasesElement(root.evalNode("typeAliases"));

/**
   * 解析MyBatis配置文件 typeAliases类型别名
   * @param parent
   */
  private void typeAliasesElement(XNode parent) {
    if (parent != null) {
      for (XNode child : parent.getChildren()) {
        /**
         * <typeAliases>
         *  <package name="hzq.mybatis.source.demo3.entity" />
         *</typeAliases>
         */
        if ("package".equals(child.getName())) {
          /**
           *获取MyBatis配置文件的包名称
           */
          String typeAliasPackage = child.getStringAttribute("name");
          /**
           *解析包目录下面的java Bean
           */
          configuration.getTypeAliasRegistry().registerAliases(typeAliasPackage);
        } else {
          /**
           * <typeAliases>
           *  <typeAlias type="hzq.mybatis.source.demo3.entity.User" alias="User"/>
           *</typeAliases>
           *
           */
          String alias = child.getStringAttribute("alias");
          String type = child.getStringAttribute("type");
          try {
            /**
             * 类实例化
             */
            Class<?> clazz = Resources.classForName(type);
            if (alias == null) {
              typeAliasRegistry.registerAlias(clazz);
            } else {
              typeAliasRegistry.registerAlias(alias, clazz);
            }
          } catch (ClassNotFoundException e) {
            throw new BuilderException("Error registering typeAlias for '" + alias + "'. Cause: " + e, e);
          }
        }
      }
    }
  }


  public void registerAliases(String packageName){
    registerAliases(packageName, Object.class);
  }

  /**
   * 解析包下面的Java Bean
   * Ignore inner classes and interfaces (including package-info.java)
   *不包含 内部类,接口 抽象类以及packgee_info类
   * @param packageName
   * @param superType
   */
  public void registerAliases(String packageName, Class<?> superType){
    //声明ResolverUtil实例
    ResolverUtil<Class<?>> resolverUtil = new ResolverUtil<Class<?>>();
    // 利用find函数找到这个包里所有的类,并且放到resolverUtil 的matches属性中
    resolverUtil.find(new ResolverUtil.IsA(superType), packageName);
    Set<Class<? extends Class<?>>> typeSet = resolverUtil.getClasses();
    //循环加载
    for(Class<?> type : typeSet){
      /**
       * 不处理内部类 接口,抽象类以及packgee_info类
       */
      // Ignore inner classes and interfaces (including package-info.java)
      // Skip also inner classes. See issue #6
      if (!type.isAnonymousClass() && !type.isInterface() && !type.isMemberClass()) {
        registerAlias(type);
      }
    }
  }

  public void registerAlias(Class<?> type) {
    /**
     * 获取类的简写名称
     */
    String alias = type.getSimpleName();
    /**
     * @Alias("user")
     * 获取javaBean上注解设置的别名
     * 这里表示如果采用包方式,没有使用注解设置别名将采用的是类的简写名称,如果使用注解设置别名了,将替换默认的别名
     */
    Alias aliasAnnotation = type.getAnnotation(Alias.class);
    if (aliasAnnotation != null) {
      alias = aliasAnnotation.value();
    } 
    registerAlias(alias, type);
  }

  public void registerAlias(String alias, Class<?> value) {
    if (alias == null) {
      throw new TypeException("The parameter alias cannot be null");
    }
    // issue #748
    /**
     * 将别名转换成小写,所以他是大小写不敏感的
     */
    String key = alias.toLowerCase(Locale.ENGLISH);
    if (TYPE_ALIASES.containsKey(key) && TYPE_ALIASES.get(key) != null && !TYPE_ALIASES.get(key).equals(value)) {
      throw new TypeException("The alias '" + alias + "' is already mapped to the value '" + TYPE_ALIASES.get(key).getName() + "'.");
    }
    /**
     * 添加别名
     * private final Map<String, Class<?>> TYPE_ALIASES = new HashMap<String, Class<?>>();
     */
    TYPE_ALIASES.put(key, value);
  }

  public void registerAlias(String alias, String value) {
    try {
      registerAlias(alias, Resources.classForName(value));
    } catch (ClassNotFoundException e) {
      throw new TypeException("Error registering type alias "+alias+" for "+value+". Cause: " + e, e);
    }
  }


以上是MyBatis配置typeAliases别名的全部过程。MyBatis的源码路程还很漫长,但是从来不放弃进步的脚步。加油!!!



相关文章:

  • 04 Mybatis源码篇---XML配置之environments环境
  • 05 Mybatis源码篇---XML配置之mappers 映射器
  • 04 Mybatis应用篇---XML映射文件之select,insert,update,delete基础介绍
  • 05 Mybatis应用篇---XML映射文件之select,insert,update,delete实战
  • IntelliJ IDEA 和 Eclipse 常用快捷键
  • 基于Maven环境进行Spring集成CXF WebService框架
  • 01 Mybatis整合Spring 由于版本引起的BUG
  • 01 shiro与spring集成
  • JAVA之自增自减运算符
  • JAVA之“==”和“equals”的区别
  • JAVA之equals对于引用类型比较的方式不同呢
  • JAVA之String,StringBuffer与StringBuilder三者之间的区别
  • JAVA之冒泡(Bubble)排序
  • JAVA之选择排序
  • JAVA之插入排序
  • 【跃迁之路】【519天】程序员高效学习方法论探索系列(实验阶段276-2018.07.09)...
  • ES6简单总结(搭配简单的讲解和小案例)
  • javascript面向对象之创建对象
  • miaov-React 最佳入门
  • Objective-C 中关联引用的概念
  • vue2.0项目引入element-ui
  • yii2中session跨域名的问题
  • Yii源码解读-服务定位器(Service Locator)
  • 测试开发系类之接口自动化测试
  • 彻底搞懂浏览器Event-loop
  • 成为一名优秀的Developer的书单
  • 从地狱到天堂,Node 回调向 async/await 转变
  • 开源地图数据可视化库——mapnik
  • 理解在java “”i=i++;”所发生的事情
  • 每天一个设计模式之命令模式
  • 容器化应用: 在阿里云搭建多节点 Openshift 集群
  • 如何优雅的使用vue+Dcloud(Hbuild)开发混合app
  • 使用 Docker 部署 Spring Boot项目
  • 自定义函数
  • 最近的计划
  • 翻译 | The Principles of OOD 面向对象设计原则
  • 小白应该如何快速入门阿里云服务器,新手使用ECS的方法 ...
  • ​马来语翻译中文去哪比较好?
  • ​软考-高级-系统架构设计师教程(清华第2版)【第9章 软件可靠性基础知识(P320~344)-思维导图】​
  • # centos7下FFmpeg环境部署记录
  • #每日一题合集#牛客JZ23-JZ33
  • (70min)字节暑假实习二面(已挂)
  • (c语言版)滑动窗口 给定一个字符串,只包含字母和数字,按要求找出字符串中的最长(连续)子串的长度
  • (介绍与使用)物联网NodeMCUESP8266(ESP-12F)连接新版onenet mqtt协议实现上传数据(温湿度)和下发指令(控制LED灯)
  • (免费领源码)python#django#mysql公交线路查询系统85021- 计算机毕业设计项目选题推荐
  • (牛客腾讯思维编程题)编码编码分组打印下标题目分析
  • (一)pytest自动化测试框架之生成测试报告(mac系统)
  • (原創) 博客園正式支援VHDL語法著色功能 (SOC) (VHDL)
  • (转)Mysql的优化设置
  • (转载)Google Chrome调试JS
  • .libPaths()设置包加载目录
  • .mat 文件的加载与创建 矩阵变图像? ∈ Matlab 使用笔记
  • .NET MAUI学习笔记——2.构建第一个程序_初级篇
  • .NET Standard / dotnet-core / net472 —— .NET 究竟应该如何大小写?
  • .Net 知识杂记