• MyBatis的TypeAliasRegistry


    Alias是别名的意思,TypeAliasRegistry的作用就是注册别名,该类存在于org.apache.ibatis.type这个包下

    public Class TypeAliasRegistry{
    	private Map<String, Class<?>> typeAliases = new HashMap<>();
    }
    
    • 1
    • 2
    • 3

    该类持有一个字典,它的作用是将String映射成一个具体类的Class对象,这样就可以通过字符串来获取具体的类别,从而实例化它。

     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 (typeAliases.containsKey(key) && typeAliases.get(key) != null && !typeAliases.get(key).equals(value)) {
          throw new TypeException("The alias '" + alias + "' is already mapped to the value '" + typeAliases.get(key).getName() + "'.");
        }
        typeAliases.put(key, value);
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    registerAlias是注册别名的方法

    1. 注册的别名不能是空
    2. 将别名转换成小写,所以Mybatis的别名注册机制对大小写是不敏感的。
    3. 判断当前Map集合是否包含该别名,如果包含并且该对应的值不等于空,并且新注册的value和之前相同,那就说明是重复注册,就抛出一个重复注册的异常信息。
    4. 将别名和对应的Class对象加入Map集合中。
      public void registerAlias(Class<?> type) {
        String alias = type.getSimpleName();
        Alias aliasAnnotation = type.getAnnotation(Alias.class);
        if (aliasAnnotation != null) {
          alias = aliasAnnotation.value();
        }
        registerAlias(alias, type);
      }
    public void registerAliases(String packageName, Class<?> superType) {
        ResolverUtil<Class<?>> resolverUtil = new ResolverUtil<>();
        resolverUtil.find(new ResolverUtil.IsA(superType), packageName);
        Set<Class<? extends Class<?>>> typeSet = resolverUtil.getClasses();
        for (Class<?> type : typeSet) {
          // 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);
          }
        }
      }
    
    这两种注册方法使用的较少,第一个是传入Class对象进行注册,此时的key值是ClassSimpleName,第二种是注册包名下的所有类。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
     public <T> Class<T> resolveAlias(String string) {
        try {
          if (string == null) {
            return null;
          }
          // issue #748
          String key = string.toLowerCase(Locale.ENGLISH);
          Class<T> value;
          if (typeAliases.containsKey(key)) {
            value = (Class<T>) typeAliases.get(key);
          } else {
            value = (Class<T>) Resources.classForName(string);
          }
          return value;
        } catch (ClassNotFoundException e) {
          throw new TypeException("Could not resolve type alias '" + string + "'.  Cause: " + e, e);
        }
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    resolveAlias,通过一个字符串来检索对应的Class对象

    1. key判断是否为空
    2. 将key值转成小写
    3. 先判断注册的Map中是否含有该类,如果没有就到类路径中加载
    4. 如果找到,则返回对应的Class文件,没找到就报类别查询异常
    public Map<String, Class<?>> getTypeAliases() {
        return Collections.unmodifiableMap(typeAliases);
      }
    
    • 1
    • 2
    • 3

    提供了一个方法来返回Map集合的不可修改视图。

    public TypeAliasRegistry() {
        registerAlias("string", String.class);
    
        registerAlias("byte", Byte.class);
        registerAlias("char", Character.class);
        registerAlias("character", Character.class);
        registerAlias("long", Long.class);
        registerAlias("short", Short.class);
        registerAlias("int", Integer.class);
        registerAlias("integer", Integer.class);
        registerAlias("double", Double.class);
        registerAlias("float", Float.class);
        registerAlias("boolean", Boolean.class);
    
        registerAlias("byte[]", Byte[].class);
        registerAlias("char[]", Character[].class);
        registerAlias("character[]", Character[].class);
        registerAlias("long[]", Long[].class);
        registerAlias("short[]", Short[].class);
        registerAlias("int[]", Integer[].class);
        registerAlias("integer[]", Integer[].class);
        registerAlias("double[]", Double[].class);
        registerAlias("float[]", Float[].class);
        registerAlias("boolean[]", Boolean[].class);
    
        registerAlias("_byte", byte.class);
        registerAlias("_char", char.class);
        registerAlias("_character", char.class);
        registerAlias("_long", long.class);
        registerAlias("_short", short.class);
        registerAlias("_int", int.class);
        registerAlias("_integer", int.class);
        registerAlias("_double", double.class);
        registerAlias("_float", float.class);
        registerAlias("_boolean", boolean.class);
    
        registerAlias("_byte[]", byte[].class);
        registerAlias("_char[]", char[].class);
        registerAlias("_character[]", char[].class);
        registerAlias("_long[]", long[].class);
        registerAlias("_short[]", short[].class);
        registerAlias("_int[]", int[].class);
        registerAlias("_integer[]", int[].class);
        registerAlias("_double[]", double[].class);
        registerAlias("_float[]", float[].class);
        registerAlias("_boolean[]", boolean[].class);
    
        registerAlias("date", Date.class);
        registerAlias("decimal", BigDecimal.class);
        registerAlias("bigdecimal", BigDecimal.class);
        registerAlias("biginteger", BigInteger.class);
        registerAlias("object", Object.class);
    
        registerAlias("date[]", Date[].class);
        registerAlias("decimal[]", BigDecimal[].class);
        registerAlias("bigdecimal[]", BigDecimal[].class);
        registerAlias("biginteger[]", BigInteger[].class);
        registerAlias("object[]", Object[].class);
    
        registerAlias("map", Map.class);
        registerAlias("hashmap", HashMap.class);
        registerAlias("list", List.class);
        registerAlias("arraylist", ArrayList.class);
        registerAlias("collection", Collection.class);
        registerAlias("iterator", Iterator.class);
    
        registerAlias("ResultSet", ResultSet.class);
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68

    在该类的构造函数中,对基本数据类型,其包装类以及一维数组都先进行了注册。可以预测该类应该只会被初始化一次。

    总结一下
    别名注册机制类很简单,核心思想是用一个HashMap保存别名和Class对象的映射关系,主要提供了下面的方法

    1. registerAlias
    2. resolveAlias
    3. getTypeAliases

    并且别名注册机制类并没有面向接口编程,默认只有一种别名注册实现。

  • 相关阅读:
    Spring Boot 整合 分布式搜索引擎 Elastic Search 实现 数据聚合
    【iptables 实战】07 iptables NAT实验
    Springboot----项目整合微信支付(用户取消订单)
    数据可视化图表总结(一)
    文科生的爬藤神器:HIEEC哈佛国际经济学论文比赛
    低代码工作流程管理系统:提升企业运营效率的利器
    System Generator学习——使用 AXI 接口和 IP 集成器
    多肽细胞穿膜肽TAT修饰牛血清白蛋白BSA/人血清白蛋白HSA/卵清白蛋白OVA纳米粒(实验要求)
    AsynchronousSocketChannel http server 接收浏览器请求 java代码 并获取浏览器请求路径
    java安全之CC1浅学(2)
  • 原文地址:https://blog.csdn.net/qq_43152622/article/details/127439194