mybatis底层组件介绍-MetaClass

MetaClass是用于解析和操作类的元数据的机制,通过Reflector和PropertyTokenizer,它可以解析复杂的属性表达式。构造函数接收类类型和ReflectorFactory,用于获取类的Reflector。findProperty方法根据点分字符串找到类的属性,而hasGetter则检查类是否存在指定的getter方法。此实现还处理了泛型和集合类型的属性获取。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

MetaClass

MetaClass通过Reflector和PropertyTokenizer,支持对复杂的属性表达上的解析

构造函数

private MetaClass(Class<?> type, ReflectorFactory reflectorFactory) {
  this.reflectorFactory = reflectorFactory;
  this.reflector = reflectorFactory.findForClass(type);
}

构造函数主要传入需要解析的类和ReflectorFactory,在执行的时候会使用传入的工厂来获取对应类的Reflector
Reflector之前介绍过,用来解析一个类的所有getter,setter和属性

findProperty

主要的作用就是通过传入的使用.串联起来的字符串,来从当前类中找到对应的属性串联起来的字符串
需要注意的是这里因为每次都是调用PropertyTokenizer的getName方法,因此不会处理下标

public String findProperty(String name) {
 StringBuilder prop = buildProperty(name, new StringBuilder());
 return prop.length() > 0 ? prop.toString() : null;
}
private StringBuilder buildProperty(String name, StringBuilder builder) {
  PropertyTokenizer prop = new PropertyTokenizer(name);
  // 使用PropertyTokenizer来解析使用.串联起来的属性表达式
  // 这里仍然以官方的测试例子为例,如果name为richType.richProperty
  if (prop.hasNext()) {
  	// 此时的prop.getName的结果是richType
  	// 从当前类的reflector中寻找名为为richType的名称,底层在查找的时候,会将字符串转为大写
    String propertyName = reflector.findPropertyName(prop.getName());
    // 将解析出来的属性,也就是richType拼接到结果中
    if (propertyName != null) {
      builder.append(propertyName);
      builder.append(".");
      // metaClassForProperty底层会使用当前类的reflector来获取名为richType的属性的类型
      // 然后继续创建richType类型对应的MetaClass
      MetaClass metaProp = metaClassForProperty(propertyName);
      // 接下来递归处理,将解析出来的属性全部拼接到builder中,并且使用.拼接
      metaProp.buildProperty(prop.getChildren(), builder);
    }
  } else {
    String propertyName = reflector.findPropertyName(name);
    if (propertyName != null) {
      builder.append(propertyName);
    }
  }
  return builder;
}

hasGetter

hasGetter比较简单,就是判断是否能够通过当前类来访问传入的使用.分割的属性串
底层就是递归地通过reflector来判断当前类是否具有指定的属性

public boolean hasGetter(String name) {
  PropertyTokenizer prop = new PropertyTokenizer(name);
  if (prop.hasNext()) {
  	// 判断当前类是否具有指定的属性
    if (reflector.hasGetter(prop.getName())) {
     // 获取对应属性的MetaClass
      MetaClass metaProp = metaClassForProperty(prop);
      return metaProp.hasGetter(prop.getChildren());
    } else {
      return false;
    }
  } else {
    return reflector.hasGetter(prop.getName());
  }
}
private MetaClass metaClassForProperty(PropertyTokenizer prop) {
  Class<?> propType = getGetterType(prop);
  return MetaClass.forClass(propType, reflectorFactory);
}
private Class<?> getGetterType(PropertyTokenizer prop) {
	// 使用不含下标的属性名来获取当前遍历的属性的类
  Class<?> type = reflector.getGetterType(prop.getName());
  // 如果当前遍历的属性的类是集合类,即表达式中使用了下标,并且当前属性的类型属于集合类
  if (prop.getIndex() != null && Collection.class.isAssignableFrom(type)) {
  	// 获取当前属性getter的返回值类型
    Type returnType = getGenericGetterType(prop.getName());
    if (returnType instanceof ParameterizedType) {
    	// 获取实际的参数类型
      Type[] actualTypeArguments = ((ParameterizedType) returnType).getActualTypeArguments();
      if (actualTypeArguments != null && actualTypeArguments.length == 1) {
      	// 集合类泛型的类型
        returnType = actualTypeArguments[0];
        // 泛型就是普通的类,直接返回
        if (returnType instanceof Class) {
          type = (Class<?>) returnType;
        } else if (returnType instanceof ParameterizedType) {
        	// 否则直接返回当前的原始类
        	// 泛型类又是一个ParameterizedType,即带有泛型的,那么直接返回原始类
          type = (Class<?>) ((ParameterizedType) returnType).getRawType();
        }
      }
    }
  }
  return type;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值