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;
}
...
}