美文网首页MyBatis源码剖析
[MyBatis源码分析 - 反射器模块 - 组件三] Obje

[MyBatis源码分析 - 反射器模块 - 组件三] Obje

作者: 小胡_鸭 | 来源:发表于2020-10-17 17:36 被阅读0次

    一、简介

      MyBatis使用 ObjectFactory 对象来创建所有需要创建的新对象,ObjectFactory 是一个接口,接口定义如下:

    public interface ObjectFactory {
    
      /**
       * 设置配置的 Properties
       */
      void setProperties(Properties properties);
    
      /**
       * 使用默认构造方法创建对象
       */
      <T> T create(Class<T> type);
    
      /**
       * 使用特定的构造方法和参数创建对象
       */
      <T> T create(Class<T> type, List<Class<?>> constructorArgTypes, List<Object> constructorArgs);
      
      /**
       * 判断类是否为集合
       */
      <T> boolean isCollection(Class<T> type);
    
    }
    

    二、DefaultObjectFactory

      DefaultObjectFactory 是该接口的默认实现类,也是唯一实现类。

    1、create(Class<T> type) &
     create(Class<T> type, List<Class<?>> constructorArgTypes, List<Object> constructorArgs)

    【功能】根据 Constructor 创建类对应的对象。
    【源码与注解】

      @Override
      public <T> T create(Class<T> type) {
        return create(type, null, null);
      }
    
      @SuppressWarnings("unchecked")
      @Override
      public <T> T create(Class<T> type, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
        // (1)解析集合接口,返回集合常用实现类类型
        Class<?> classToCreate = resolveInterface(type);
        // (2)实例化对象
        // we know types are assignable
        return (T) instantiateClass(classToCreate, constructorArgTypes, constructorArgs);
      }
    

    【解析】
    (1)解析集合接口类型,获取其对应的常用的实现类,源码如下:

      // 对于常见的集合接口,返回其对应常用的实现类
      protected Class<?> resolveInterface(Class<?> type) {
        Class<?> classToCreate;
        if (type == List.class || type == Collection.class || type == Iterable.class) {
          classToCreate = ArrayList.class;
        } else if (type == Map.class) {
          classToCreate = HashMap.class;
        } else if (type == SortedSet.class) { // issue #510 Collections Support
          classToCreate = TreeSet.class;
        } else if (type == Set.class) {
          classToCreate = HashSet.class;
        } else {
          classToCreate = type;
        }
        return classToCreate;
      }
    

    (2)调用 #instantiateClass(Class<T> type, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) 生成实例化对象,源码如下:

      <T> T instantiateClass(Class<T> type, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
        try {
          Constructor<T> constructor;
          // (2.1)如果构造参数类型或者构造参数为空,则对象要通过默认构造方法来创建
          if (constructorArgTypes == null || constructorArgs == null) {
            constructor = type.getDeclaredConstructor();
            if (!constructor.isAccessible()) {
              constructor.setAccessible(true);
            }
            return constructor.newInstance();
          }
          // (2.2)根据构造参数类型获取对应构造方法并创建对象
          constructor = type.getDeclaredConstructor(constructorArgTypes.toArray(new Class[constructorArgTypes.size()]));
          if (!constructor.isAccessible()) {
            constructor.setAccessible(true);
          }
          return constructor.newInstance(constructorArgs.toArray(new Object[constructorArgs.size()]));
        } catch (Exception e) {
          // (2.3)拼接 argTypes,作为异常信息返回
          StringBuilder argTypes = new StringBuilder();
          if (constructorArgTypes != null && !constructorArgTypes.isEmpty()) {
            for (Class<?> argType : constructorArgTypes) {
              argTypes.append(argType.getSimpleName());
              argTypes.append(",");
            }
            argTypes.deleteCharAt(argTypes.length() - 1); // remove trailing ,
          }
          // (2.4)拼接 argValues,作为异常信息返回
          StringBuilder argValues = new StringBuilder();
          if (constructorArgs != null && !constructorArgs.isEmpty()) {
            for (Object argValue : constructorArgs) {
              argValues.append(String.valueOf(argValue));
              argValues.append(",");
            }
            argValues.deleteCharAt(argValues.length() - 1); // remove trailing ,
          }
          // (2.5)创建对象失败,抛出异常
          throw new ReflectionException("Error instantiating " + type + " with invalid types (" + argTypes + ") or values (" + argValues + "). Cause: " + e, e);
        }
      }
    
    • (2.1)使用默认构造方法创建对象
    • (2.2)使用含参构造方法创建对象
    • (2.3)拼接传入的构造参数类型,放在异常信息中返回
    • (2.4)拼接传入的构造参数值,放在异常信息中返回
    • (2.5)创建对象失败,抛出异常

    2、isCollection(Class<T> type)

    【功能】判断是否为集合类型
    【源码与注解】

      @Override
      public <T> boolean isCollection(Class<T> type) {
        return Collection.class.isAssignableFrom(type);
      }
    

    相关文章

      网友评论

        本文标题:[MyBatis源码分析 - 反射器模块 - 组件三] Obje

        本文链接:https://www.haomeiwen.com/subject/vylfmktx.html