Mybatis基础支持层-反射模块-02

Type/TypeParameterResolver

Posted by Claire on June 13, 2020

mybatis基础支持层-反射模块:TypeParameterResolver

一、Type

  • 首先了解一些基础类型的含义,Type有哪些实现类和子接口:Class,ParameterizedType,GenericArrayType,TypeVariable,WildcardType
public interface Type {
    /**
     * Returns a string describing this type, including information
     * about any type parameters.
     *
     * @implSpec The default implementation calls {@code toString}.
     *
     * @return a string describing this type
     * @since 1.8
     */
    default String getTypeName() {
        return toString();
    }
}
  • Class表示JVM中的一个类或者接口,可以通过.class/getClass()/Class.forName/ClassLoader等方式获取一个类或者接口的Class

  • ParameterizedType 表示参数化类型,例子:List,Map<Integer,String>,Service

public interface ParameterizedType extends Type {
    /**
     获取参数化类型的实际类型列表  Map<String,Integer>就是String Integer
     */
    Type[] getActualTypeArguments();

    /**
      参数化类型中的原始类型,例子:List<String> -->List
     */
    Type getRawType();

    /**
    返回类型所属的类型
     */
    Type getOwnerType();
}
  • TypeVariable 标识的是类型变量,反应在JVM编译泛型前的信息
public interface TypeVariable<D extends GenericDeclaration> extends Type, AnnotatedElement {
    /**
     获取类型的上边界,默认Object List<T extends User> -->Use是上边界
    */
    Type[] getBounds();

    /**
      获取声明该类型的原始类型,class Test<T extends User> -->Test
     */
    D getGenericDeclaration();

    /**
     湖片区源码中定义的名字 T
     */
    String getName();

    /**
     * Returns an array of AnnotatedType objects that represent the use of
     * types to denote the upper bounds of the type parameter represented by
     * this TypeVariable. The order of the objects in the array corresponds to
     * the order of the bounds in the declaration of the type parameter.
     *
     * Returns an array of length 0 if the type parameter declares no bounds.
     *
     * @return an array of objects representing the upper bounds of the type variable
     * @since 1.8
     */
     AnnotatedType[] getAnnotatedBounds();
}

二、TypeParameterResolver

  • 接下来还是切入TypeParameterResolver

1.addGetMethod

   private void addGetMethod(String name, Method method) {
    if (isValidPropertyName(name)) {
        //记录方法,绑定回调方法
      getMethods.put(name, new MethodInvoker(method));
      Type returnType = TypeParameterResolver.resolveReturnType(method, type);
      //记录返回值类型
      getTypes.put(name, typeToClass(returnType));
    }
  }
  • 以上方法的流程大约如下,除了resolveReturnType的流程,还有resolveFieldType resolveParamTypes,包含返回值类型,属性类型,参数类型的解析,最终就是调用resolveType 进行类型的解析
  1. resolveReturnType --> 2. resolveType -->(
     3.1 resolveTypeVar --> 4scanSuperTypes
     3.2 resolveParameterizedType -->(
          ...,
         4 resolveWildcardType -->5 resolveWildcardTypeBounds
          )
     3.3 resolveGenericArrayType ->(...)
      )

2.resolveType

 private static Type resolveType(Type type, Type srcType, Class<?> declaringClass) {
    if (type instanceof TypeVariable) {
      return resolveTypeVar((TypeVariable<?>) type, srcType, declaringClass);
    } else if (type instanceof ParameterizedType) {
      return resolveParameterizedType((ParameterizedType) type, srcType, declaringClass);
    } else if (type instanceof GenericArrayType) {
      return resolveGenericArrayType((GenericArrayType) type, srcType, declaringClass);
    } else {
      return type;
    }
  }

3.resolveParameterizedType

  • 内部有递归调用方法,直到所有参数都是基础类型,不含有任何包装对象,如果无匹配的上界,默认为Object
  private static ParameterizedType resolveParameterizedType(ParameterizedType parameterizedType, Type srcType, Class<?> declaringClass) {
    Class<?> rawType = (Class<?>) parameterizedType.getRawType();
    Type[] typeArgs = parameterizedType.getActualTypeArguments();
    Type[] args = new Type[typeArgs.length];
    for (int i = 0; i < typeArgs.length; i++) {
      if (typeArgs[i] instanceof TypeVariable) {
        args[i] = resolveTypeVar((TypeVariable<?>) typeArgs[i], srcType, declaringClass);
      } else if (typeArgs[i] instanceof ParameterizedType) {
          //进行递归解析类型
        args[i] = resolveParameterizedType((ParameterizedType) typeArgs[i], srcType, declaringClass);
      } else if (typeArgs[i] instanceof WildcardType) {
        args[i] = resolveWildcardType((WildcardType) typeArgs[i], srcType, declaringClass);
      } else {
        args[i] = typeArgs[i];
      }
    }
    return new ParameterizedTypeImpl(rawType, null, args);

4.resolveTypeVar

  • 经过处理,类型都会是TypeVariable类型,resolveTypeVar方法来看一下
private static Type resolveTypeVar(TypeVariable<?> typeVar, Type srcType, Class<?> declaringClass) {
    Type result;
    Class<?> clazz;
    if (srcType instanceof Class) {
      clazz = (Class<?>) srcType;
    } else if (srcType instanceof ParameterizedType) {
        //如果对应类也需要解析参数类型
      ParameterizedType parameterizedType = (ParameterizedType) srcType;
      clazz = (Class<?>) parameterizedType.getRawType();
    } else {
      throw new IllegalArgumentException("The 2nd arg must be Class or ParameterizedType, but was: " + srcType.getClass());
    }

    //如果对应类类型无需转换
    if (clazz == declaringClass) {
        //获取上界
      Type[] bounds = typeVar.getBounds();
      if (bounds.length > 0) {
        return bounds[0];
      }
      //默认上界
      return Object.class;
    }

//获取父类类型
    Type superclass = clazz.getGenericSuperclass();
    //扫描父类
    result = scanSuperTypes(typeVar, srcType, declaringClass, clazz, superclass);
    if (result != null) {
      return result;
    }

//获取父接口
    Type[] superInterfaces = clazz.getGenericInterfaces();
    for (Type superInterface : superInterfaces) {
        //扫描父接口
      result = scanSuperTypes(typeVar, srcType, declaringClass, clazz, superInterface);
      if (result != null) {
        return result;
      }
    }
    return Object.class;
  }

5.scanSuperTypes

  • scanSuperTypes的任务是递归整个继承结构并完成类型变量的解析
 private static Type scanSuperTypes(TypeVariable<?> typeVar, Type srcType, Class<?> declaringClass, Class<?> clazz, Type superclass) {
    if (superclass instanceof ParameterizedType) {
      ParameterizedType parentAsType = (ParameterizedType) superclass;
      Class<?> parentAsClass = (Class<?>) parentAsType.getRawType();
      TypeVariable<?>[] parentTypeVars = parentAsClass.getTypeParameters();
      if (srcType instanceof ParameterizedType) {
        parentAsType = translateParentTypeVars((ParameterizedType) srcType, clazz, parentAsType);
      }
      if (declaringClass == parentAsClass) {
        for (int i = 0; i < parentTypeVars.length; i++) {
          if (typeVar == parentTypeVars[i]) {
            return parentAsType.getActualTypeArguments()[i];
          }
        }
      }
      if (declaringClass.isAssignableFrom(parentAsClass)) {
        return resolveTypeVar(typeVar, parentAsType, declaringClass);
      }
    } else if (superclass instanceof Class && declaringClass.isAssignableFrom((Class<?>) superclass)) {
      return resolveTypeVar(typeVar, superclass, declaringClass);
    }
    return null;
  }
  • 以上scanSuperTypes方法会比较复杂一些,先找到待解析的参数,再在层层解析的映射中查找类型的映射,直到定位基础类中的一种,最终构造返回类型
  • resolveGenericArrayType是专门用于解析数组元素类型的
  • 还有一块是通配符表达式,WildcardType,主要在于确定上界和下界
static class WildcardTypeImpl implements WildcardType {
    private Type[] lowerBounds;

    private Type[] upperBounds;

    WildcardTypeImpl(Type[] lowerBounds, Type[] upperBounds) {
      super();
      this.lowerBounds = lowerBounds;
      this.upperBounds = upperBounds;
    }
    ...
}