mybatis之TypeParameterResolver工具类

TypeParameterResolver

  • 它是一个工具类,提供了一系列静态
    方法来解析指定类中的宇段、方法返回值或方法参数的类型。 TypeParameterResolver 中各个静
    态方法之间的调用关系大致如图 2-11 所示,为保持清晰,其中递归调用没有表现出来,在后面
    的代码分析过程中会进行强调。
    在这里插入图片描述
public class TypeParameterResolver {

    /**
     * @return The field type as {@link Type}. If it has type parameters in the declaration,<br>
     *         they will be resolved to the actual runtime {@link Type}s.
     */
    public static Type resolveFieldType(Field field, Type srcType) {
        // 返回属性的类型,如果是泛型,则为这次的实际类型
        Type fieldType = field.getGenericType();
        // 返回其声明类型
        Class<?> declaringClass = field.getDeclaringClass();
        return resolveType(fieldType, srcType, declaringClass);
    }

    /**
     * @return The return type of the method as {@link Type}. If it has type parameters in the declaration,<br>
     *         they will be resolved to the actual runtime {@link Type}s.
     */
    public static Type resolveReturnType(Method method, Type srcType) {
        Type returnType = method.getGenericReturnType();
        Class<?> declaringClass = method.getDeclaringClass();
        return resolveType(returnType, srcType, declaringClass);
    }

    /**
     * @return The parameter types of the method as an array of {@link Type}s. If they have type parameters in the declaration,<br>
     *         they will be resolved to the actual runtime {@link Type}s.
     */

    /**
     * 解析方法入参
     * @param method 目标方法
     * @param srcType 目标方法所属的类
     * @return 解析结果
     */
    public static Type[] resolveParamTypes(Method method, Type srcType) {
        // 取出方法的所有入参
        Type[] paramTypes = method.getGenericParameterTypes();
        // 定义目标方法的类或接口
        Class<?> declaringClass = method.getDeclaringClass();
        // 解析结果
        Type[] result = new Type[paramTypes.length];
        for (int i = 0; i < paramTypes.length; i++) {
            // 对每个入参依次调用resolveType方法
            result[i] = resolveType(paramTypes[i], srcType, declaringClass);
        }
        return result;
    }

    /**
     * 解析变量的实际类型
     * @param type 变量的类型
     * @param srcType 变量所属于的类
     * @param declaringClass 定义变量的类
     * @return 解析结果
     */
    private static Type resolveType(Type type, Type srcType, Class<?> declaringClass) {
        if (type instanceof TypeVariable) { // 如果是类型变量,例如“Map<K,V>”中的“K”、“V”就是类型变量。
            return resolveTypeVar((TypeVariable<?>) type, srcType, declaringClass);
        } else if (type instanceof ParameterizedType) { // 如果是参数化类型,例如“Collection<String>”就是参数化的类型。
            return resolveParameterizedType((ParameterizedType) type, srcType, declaringClass);
        } else if (type instanceof GenericArrayType) { // 如果是包含ParameterizedType或者TypeVariable元素的列表
            return resolveGenericArrayType((GenericArrayType) type, srcType, declaringClass);
        } else {
            return type;
        }
    }
  • TypeParameterResolver 中通过 resolveFieldType()方法,resolveReturnType() 方法,
    resolveParamTypes()方法分别解析宇段类型、方法返回值类型和方法参数列表中各个参数的类型.
     * 解析泛型列表的实际类型
     * @param genericArrayType 泛型列表变量类型
     * @param srcType 变量所属于的类
     * @param declaringClass 定义变量的类
     * @return 解析结果
     */
    private static Type resolveGenericArrayType(GenericArrayType genericArrayType, Type srcType, Class<?> declaringClass) {
        Type componentType = genericArrayType.getGenericComponentType();
        Type resolvedComponentType = null;
        if (componentType instanceof TypeVariable) { // 元素类型是类变量。例如genericArrayType为T[]则属于这种情况
            resolvedComponentType = resolveTypeVar((TypeVariable<?>) componentType, srcType, declaringClass);
        } else if (componentType instanceof GenericArrayType) { // 元素类型是泛型列表。例如genericArrayType为T[][]则属于这种情况
            resolvedComponentType = resolveGenericArrayType((GenericArrayType) componentType, srcType, declaringClass);
        } else if (componentType instanceof ParameterizedType) { // 元素类型是参数化类型。例如genericArrayType为Collection<T>[]则属于这种情况
            resolvedComponentType = resolveParameterizedType((ParameterizedType) componentType, srcType, declaringClass);
        }
        if (resolvedComponentType instanceof Class) {
            return Array.newInstance((Class<?>) resolvedComponentType, 0).getClass();
        } else {
            return new GenericArrayTypeImpl(resolvedComponentType);
        }
    }

    /**
     * 解析参数化类型的实际结果
     * @param parameterizedType 参数化类型的变量
     * @param srcType 该变量所属于的类
     * @param declaringClass 定义该变量的类
     * @return 参数化类型的实际结果
     */
    private static ParameterizedType resolveParameterizedType(ParameterizedType parameterizedType, Type srcType, Class<?> declaringClass) {
        // 变量的原始类型。本示例中为List
        Class<?> rawType = (Class<?>) parameterizedType.getRawType();
        // 获取类型参数。本示例中只有一个类型参数T
        Type[] typeArgs = parameterizedType.getActualTypeArguments();
        // 类型参数的实际类型
        Type[] args = new Type[typeArgs.length];
        for (int i = 0; i < typeArgs.length; i++) { // 依次处理每一个类型参数
            if (typeArgs[i] instanceof TypeVariable) { // 类型参数是类型变量。例如parameterizedType为List<T>则属于这种情况
                args[i] = resolveTypeVar((TypeVariable<?>) typeArgs[i], srcType, declaringClass);
            } else if (typeArgs[i] instanceof ParameterizedType) { // 类型参数是参数化类型。例如parameterizedType为List<List<T>>则属于这种情况
                args[i] = resolveParameterizedType((ParameterizedType) typeArgs[i], srcType, declaringClass);
            } else if (typeArgs[i] instanceof WildcardType) { // 类型参数是通配符泛型。例如parameterizedType为List<? extends Number>则属于这种情况
                args[i] = resolveWildcardType((WildcardType) typeArgs[i], srcType, declaringClass);
            } else { // 类型参数是确定的类型。例如parameterizedType为List<String>则会进入这里
                args[i] = typeArgs[i];
            }
        }
        return new ParameterizedTypeImpl(rawType, null, args);
    }

    private static Type resolveWildcardType(WildcardType wildcardType, Type srcType, Class<?> declaringClass) {
        Type[] lowerBounds = resolveWildcardTypeBounds(wildcardType.getLowerBounds(), srcType, declaringClass);
        Type[] upperBounds = resolveWildcardTypeBounds(wildcardType.getUpperBounds(), srcType, declaringClass);
        return new WildcardTypeImpl(lowerBounds, upperBounds);
    }

    private static Type[] resolveWildcardTypeBounds(Type[] bounds, Type srcType, Class<?> declaringClass) {
        Type[] result = new Type[bounds.length];
        for (int i = 0; i < bounds.length; i++) {
            if (bounds[i] instanceof TypeVariable) {
                result[i] = resolveTypeVar((TypeVariable<?>) bounds[i], srcType, declaringClass);
            } else if (bounds[i] instanceof ParameterizedType) {
                result[i] = resolveParameterizedType((ParameterizedType) bounds[i], srcType, declaringClass);
            } else if (bounds[i] instanceof WildcardType) {
                result[i] = resolveWildcardType((WildcardType) bounds[i], srcType, declaringClass);
            } else {
                result[i] = bounds[i];
            }
        }
        return result;
    }

    /**
     * 解析泛型变量的实际结果
     * @param typeVar 泛型变量
     * @param srcType 该变量所属于的类
     * @param declaringClass 定义该变量的类
     * @return 泛型变量的实际结果
     */
    private static Type resolveTypeVar(TypeVariable<?> typeVar, Type srcType, Class<?> declaringClass) {
        // 解析出的泛型变量的结果
        Type result;
        Class<?> clazz;
        if (srcType instanceof Class) { // 该变量属于确定的类。该示例中,变量T属于Student类,Student类是一个确定的类
            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) { // 变量属于的类和定义变量的类一致。该示例中,变量T属于Student,定义于User
            // 确定泛型变量的上届
            Type[] bounds = typeVar.getBounds();
            if (bounds.length > 0) {
                return bounds[0];
            }
            // 泛型变量无上届,则上届为Object
            return Object.class;
        }

        // 获取变量属于的类的父类。在该示例中,变量属于Student类,其父类为User<Number>类
        Type superclass = clazz.getGenericSuperclass();
        // 扫描父类,查看能否确定边界。该示例中,能确定出边界为Number
        result = scanSuperTypes(typeVar, srcType, declaringClass, clazz, superclass);
        if (result != null) {
            return result;
        }

        // 获取变量属于的类的接口
        Type[] superInterfaces = clazz.getGenericInterfaces();
        // 依次扫描各个父接口,查看能否确定边界。该示例中,Student类无父接口
        for (Type superInterface : superInterfaces) {
            result = scanSuperTypes(typeVar, srcType, declaringClass, clazz, superInterface);
            if (result != null) {
                return result;
            }
        }
        // 如果始终找不到结果,则未定义。即为Object
        return Object.class;
    }

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

    private static ParameterizedType translateParentTypeVars(ParameterizedType srcType, Class<?> srcClass, ParameterizedType parentType) {
        Type[] parentTypeArgs = parentType.getActualTypeArguments();
        Type[] srcTypeArgs = srcType.getActualTypeArguments();
        TypeVariable<?>[] srcTypeVars = srcClass.getTypeParameters();
        Type[] newParentArgs = new Type[parentTypeArgs.length];
        boolean noChange = true;
        for (int i = 0; i < parentTypeArgs.length; i++) {
            if (parentTypeArgs[i] instanceof TypeVariable) {
                for (int j = 0; j < srcTypeVars.length; j++) {
                    if (srcTypeVars[j] == parentTypeArgs[i]) {
                        noChange = false;
                        newParentArgs[i] = srcTypeArgs[j];
                    }
                }
            } else {
                newParentArgs[i] = parentTypeArgs[i];
            }
        }
        return noChange ? parentType : new ParameterizedTypeImpl((Class<?>) parentType.getRawType(), null, newParentArgs);
    }

    private TypeParameterResolver() {
        super();
    }

    /**
     * 泛型参数泛型
     * 以Map<String,Object为例>
     */
    static class ParameterizedTypeImpl implements ParameterizedType {
        // 所属对象
        private Class<?> rawType;
        // 泛型类型,例如Map
        private Type ownerType;
        // 内部类型,例如 Sting,Object
        private Type[] actualTypeArguments;

        public ParameterizedTypeImpl(Class<?> rawType, Type ownerType, Type[] actualTypeArguments) {
            super();
            this.rawType = rawType;
            this.ownerType = ownerType;
            this.actualTypeArguments = actualTypeArguments;
        }

        @Override
        public Type[] getActualTypeArguments() {
            return actualTypeArguments;
        }

        @Override
        public Type getOwnerType() {
            return ownerType;
        }

        @Override
        public Type getRawType() {
            return rawType;
        }

        @Override
        public String toString() {
            return "ParameterizedTypeImpl [rawType=" + rawType + ", ownerType=" + ownerType + ", actualTypeArguments=" + Arrays.toString(actualTypeArguments) + "]";
        }
    }

    /**
     * 上下界的泛型
     */
    static class WildcardTypeImpl implements WildcardType {
        private Type[] lowerBounds;

        private Type[] upperBounds;

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

        @Override
        public Type[] getLowerBounds() {
            return lowerBounds;
        }

        @Override
        public Type[] getUpperBounds() {
            return upperBounds;
        }
    }

    /**
     * 列表类泛型
     */
    static class GenericArrayTypeImpl implements GenericArrayType {
        private Type genericComponentType;

        GenericArrayTypeImpl(Type genericComponentType) {
            super();
            this.genericComponentType = genericComponentType;
        }

        @Override
        public Type getGenericComponentType() {
            return genericComponentType;
        }
    }
  • 这段解析的代码涉及到参数的泛型,泛型的上下界,获取泛型的实际结果,参数化类型等等许多,可以说是反射中解析的各个参数的核心代码。下边总结出一些常用代码:
public class ClassA<K,V> {
    public Map<K,V> map;
}

public class SubClassA<T> extends ClassA {
}

public class TestType {
    SubClassA<Long> sa = new SubClassA();
}
    Field field = SubClassA.class.getSuperclass().getDeclaredField("map");
    System.out.println(field.getGenericType());
    System.out.println(field.getGenericType() instanceof ParameterizedType);
    System.out.println(field.getType());
    
    --------------------------------
    
    java.util.Map<K, V>
    true
    interface java.util.Map
  • field.getGenericType();获取该参数的参数化类型
  • field.getType():获取该参数的类型
  • ParameterizedType parameterizedType = (ParameterizedType) srcType;
  • clazz = (Class<?>) parameterizedType.getRawType(); 获取参数化类型的原始类型
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Mybatis-Plus是一个优秀的Mybatis增强工具,它可以极大地简化Mybatis的开发流程,提高开发效率。下面是一个基于Mybatis-Plus的工具类示例: ```java public class MybatisPlusUtils { /** * 获取MybatisPlus的全局配置对象 * @return GlobalConfig对象 */ public static GlobalConfig getGlobalConfig() { GlobalConfig globalConfig = new GlobalConfig(); //设置主键自增策略 globalConfig.setSqlInjector(new AutoSqlInjector()); globalConfig.setDbConfig(new GlobalConfig.DbConfig() .setLogicDeleteValue("1") .setLogicNotDeleteValue("0") .setIdType(IdType.AUTO)); return globalConfig; } /** * 获取MybatisPlus的数据源对象 * @param driver 数据库驱动 * @param url 数据库连接URL * @param username 数据库用户名 * @param password 数据库密码 * @return DataSource对象 */ public static DataSource getDataSource(String driver, String url, String username, String password) { DruidDataSource dataSource = new DruidDataSource(); dataSource.setDriverClassName(driver); dataSource.setUrl(url); dataSource.setUsername(username); dataSource.setPassword(password); return dataSource; } /** * 获取MybatisPlus的SqlSessionFactory对象 * @param dataSource 数据源对象 * @param globalConfig 全局配置对象 * @return SqlSessionFactory对象 */ public static SqlSessionFactory getSqlSessionFactory(DataSource dataSource, GlobalConfig globalConfig) { MybatisConfiguration configuration = new MybatisConfiguration(); //开启驼峰命名规则 configuration.setMapUnderscoreToCamelCase(true); //将全局配置对象添加到Mybatis配置对象中 configuration.setGlobalConfig(globalConfig); SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); return builder.build(configuration, new MybatisPlusInterceptor[]{new PaginationInterceptor()}, dataSource); } /** * 获取MybatisPlus的SqlSession对象 * @param sqlSessionFactory SqlSessionFactory对象 * @return SqlSession对象 */ public static SqlSession getSqlSession(SqlSessionFactory sqlSessionFactory) { return sqlSessionFactory.openSession(); } } ``` 使用该工具类,可以方便地获取Mybatis-Plus所需的全局配置、数据源、SqlSessionFactory和SqlSession对象。在使用时,只需要传入相应的参数即可。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值