Mybatis源码分析(七):配置属性typeAliases和typeAliasesPackage

一.typeAliasesPackage源码分析

1. spring中的配置

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="typeAliasesPackage" value="com.zzy.model"/>
</bean>

2.typeAliasesPackage源码

A.typeAliasesPackage属性解析

if (hasLength(this.typeAliasesPackage)) {
      String[] typeAliasPackageArray = tokenizeToStringArray(this.typeAliasesPackage,
          ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
      for (String packageToScan : typeAliasPackageArray) {
        configuration.getTypeAliasRegistry().registerAliases(packageToScan,
                typeAliasesSuperType == null ? Object.class : typeAliasesSuperType);
        if (LOGGER.isDebugEnabled()) {
          LOGGER.debug("Scanned package: '" + packageToScan + "' for aliases");
        }
      }
}

描述:配置typeAliasesPackage属性的情况下通过 

tokenizeToStringArray(this.typeAliasesPackage,

          ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS)

获取package数组,此处只配置了一个包,返回的是只有一个包的数组,截图如下:

 

循环包数组,依次对包数组中的类就行处理,处理方法

registerAliases(String packageName, Class<?> superType)

B. registerAliases源码分析

public void registerAliases(String packageName, Class<?> superType){
    ResolverUtil<Class<?>> resolverUtil = new ResolverUtil<Class<?>>();
    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);
      }
    }
  }

描述:find的作用就是将package包下所有

.class文件转换成class对象[例如:com/zzy/model/Student.class]放入到set集合matches

resolverUtil.getClasses()这个方法就是将find生成的set集合拿到。

ResolverUtil类中的find()和getClasses()下文带大家看看源码。

然后通过 registerAlias(type);将别名和class对象映射关系注册到TYPE_ALIASES这个map中,而这个map是被封装在TypeAliasRegistry对象中的。 而这个类的实例是被包装到数据管理对象Configuration中的。

所以再次证明Configuration是个数据管理的大管家。

以上内容叙述了整个typeAliasesPackage被解析的过程。

 

C.上面内容涉及到的resolverUtil.find()、resolverUtil.getClasses()、registerAlias()接下来看看这些方法的源码。

 c1.  resolverUtil.find()

public ResolverUtil<T> find(Test test, String packageName) {
    String path = getPackagePath(packageName);

    try {
      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;
  }

上面代码的描述:

通过将包名【com.zzy.model】转换成path【com/zzy/mode】

然后利用VFS.getInstance().list(path);获奖path下所有的资源文件,获取到的资源文件如下:

[com/zzy/model/Student.class, com/zzy/model/User.class]

 

通过

for (String child : children) {
        if (child.endsWith(".class")) {
          addIfMatching(test, child);
        }
}

放入到set集合matches。

c2.resolverUtil.getClasses()

public Set<Class<? extends T>> getClasses() {
    return matches;
  }

c3.registerAlias(type)

public void registerAlias(Class<?> type) {
    String alias = type.getSimpleName();
    Alias aliasAnnotation = type.getAnnotation(Alias.class);
    if (aliasAnnotation != null) {
      alias = aliasAnnotation.value();
    } 
    registerAlias(alias, type);
  }

其中 registerAlias(alias, type);完成的工作就是把alias和class对象的映射关系放入到了map中。最后configuration持有typeAliasRegistry引用,所以别名数组最终都被存放到了configuration中。

3.源码中默认基本类型和基本类型数组和别名的对应关系,方便大家使用。

   registerAlias("string", String.class);

    registerAlias("byte", Byte.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("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("_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("_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);

二.typeAliases源码分析

if (!isEmpty(this.typeAliases)) {
      for (Class<?> typeAlias : this.typeAliases) {
        configuration.getTypeAliasRegistry().registerAlias(typeAlias);
        if (LOGGER.isDebugEnabled()) {
          LOGGER.debug("Registered type alias: '" + typeAlias + "'");
        }
      }
}

其中registerAlias()方法源码

public void registerAlias(Class<?> type) {
    String alias = type.getSimpleName();
    Alias aliasAnnotation = type.getAnnotation(Alias.class);
    if (aliasAnnotation != null) {
      alias = aliasAnnotation.value();
    } 
    registerAlias(alias, type);
  }

registerAlias(alias, type);最后将alias和class对象注册到一个map中,typeAliasesPackage也调用到了该方法注册映射关系到map「殊途同归」。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值