Mybatis-MetaObject,MetaClass源码解析

Mybatis3.5.1源码分析

  1. Mybatis-SqlSessionFactoryBuilder,XMLConfigBuilder,XPathParser源码解析
  2. Mybatis-Configuration源码解析
  3. Mybatis-事务对象源码解析
  4. Mybatis-数据源源码解析
  5. Mybatis缓存策略源码解析
  6. Mybatis-DatabaseIdProvider源码解析
  7. Mybatis-TypeHandler源码解析
  8. Mybatis-Reflector源码解析
  9. Mybatis-ObjectFactory,ObjectWrapperFactory源码分析
  10. Mybatis-Mapper各类标签封装类源码解析
  11. Mybatis-XMLMapperBuilder,XMLStatmentBuilder源码分析
  12. Mybatis-MapperAnnotationBuilder源码分析
  13. [Mybatis-MetaObject,MetaClass源码解析]//www.greatytc.com/p/f51fa552f30a)
  14. Mybatis-LanguageDriver源码解析
  15. Mybatis-SqlSource源码解析
  16. Mybatis-SqlNode源码解析
  17. Mybatis-KeyGenerator源码解析
  18. Mybatis-Executor源码解析
  19. Mybatis-ParameterHandler源码解析
  20. Mybatis-StatementHandler源码解析
  21. Mybatis-DefaultResultSetHandler(一)源码解析
  22. Mybatis-DefaultResultSetHandler(二)源码解析
  23. Mybatis-ResultHandler,Cursor,RowBounds 源码分析
  24. Mybatis-MapperProxy源码解析
  25. Mybatis-SqlSession源码解析
  26. Mybatis-Interceptor源码解析

MetaObject

/**
 *    Copyright 2009-2019 the original author or authors.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */
package org.apache.ibatis.reflection;

import java.util.Collection;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.reflection.factory.ObjectFactory;
import org.apache.ibatis.reflection.property.PropertyTokenizer;
import org.apache.ibatis.reflection.wrapper.BeanWrapper;
import org.apache.ibatis.reflection.wrapper.CollectionWrapper;
import org.apache.ibatis.reflection.wrapper.MapWrapper;
import org.apache.ibatis.reflection.wrapper.ObjectWrapper;
import org.apache.ibatis.reflection.wrapper.ObjectWrapperFactory;

/**
 * 元对象
 * <p>
 *     只是对对象附加一下更加便捷描述的功能,Meta一般表示对一个东西的描述信息
 * </p>
 * @author Clinton Begin
 */
public class MetaObject {

  /**
   * 元素对象,当前类对象
   */
  private final Object originalObject;
  private final ObjectWrapper objectWrapper;
  private final ObjectFactory objectFactory;
  private final ObjectWrapperFactory objectWrapperFactory;
  private final ReflectorFactory reflectorFactory;

  private MetaObject(Object object, ObjectFactory objectFactory, ObjectWrapperFactory objectWrapperFactory, ReflectorFactory reflectorFactory) {
    this.originalObject = object;
    this.objectFactory = objectFactory;
    this.objectWrapperFactory = objectWrapperFactory;
    this.reflectorFactory = reflectorFactory;

    if (object instanceof ObjectWrapper) {
      //如果参数对象实现了ObjectWrapper
      this.objectWrapper = (ObjectWrapper) object;
    } else if (objectWrapperFactory.hasWrapperFor(object)) {
      //如果objectWrapperFactory已经包装了对象,对用objectWrapperFactory的getWrapperFor
      this.objectWrapper = objectWrapperFactory.getWrapperFor(this, object);
    } else if (object instanceof Map) {
      //是一个Map对象,使用mybatis的MapWrapper
      this.objectWrapper = new MapWrapper(this, (Map) object);
    } else if (object instanceof Collection) {
      //是一个CollectionWrapper对象
      this.objectWrapper = new CollectionWrapper(this, (Collection) object);
    } else {
      //其他默认使用BeanWrapper
      this.objectWrapper = new BeanWrapper(this, object);
    }
  }

  public static MetaObject forObject(Object object, ObjectFactory objectFactory, ObjectWrapperFactory objectWrapperFactory, ReflectorFactory reflectorFactory) {
    if (object == null) {
      return SystemMetaObject.NULL_META_OBJECT;
    } else {
      return new MetaObject(object, objectFactory, objectWrapperFactory, reflectorFactory);
    }
  }

  public ObjectFactory getObjectFactory() {
    return objectFactory;
  }

  public ObjectWrapperFactory getObjectWrapperFactory() {
    return objectWrapperFactory;
  }

  public ReflectorFactory getReflectorFactory() {
    return reflectorFactory;
  }

  public Object getOriginalObject() {
    return originalObject;
  }

  public String findProperty(String propName, boolean useCamelCaseMapping) {
    return objectWrapper.findProperty(propName, useCamelCaseMapping);
  }

  /**
   * 直接调用 {@link ObjectWrapper#getGetterNames()}
   */
  public String[] getGetterNames() {
    return objectWrapper.getGetterNames();
  }

  /**
   * 直接调用 {@link ObjectWrapper#getSetterNames()}
   */
  public String[] getSetterNames() {
    return objectWrapper.getSetterNames();
  }

  /**
   * 直接调用 {@link ObjectWrapper#getSetterType(String)}
   */
  public Class<?> getSetterType(String name) {
    return objectWrapper.getSetterType(name);
  }

  /**
   * 直接调用 {@link ObjectWrapper#getGetterType(String)}
   */
  public Class<?> getGetterType(String name) {
    return objectWrapper.getGetterType(name);
  }

  /**
   * 直接调用 {@link ObjectWrapper#hasSetter(String)}
   */
  public boolean hasSetter(String name) {
    return objectWrapper.hasSetter(name);
  }

  /**
   * 直接调用 {@link ObjectWrapper#hasGetter(String)}
   */
  public boolean hasGetter(String name) {
    return objectWrapper.hasGetter(name);
  }

  /**
   * 判断PropertyTokenizer(参数name)是否还存在下一级,如果存在递归该方法,指定找到尾部,再获取其值。
   * 最后是通过 {@link ObjectWrapper#get(PropertyTokenizer)} 获得对应(参数name)的对象
   * <p>
   *     例:<br/>
   *     以(参数name='order[0].name')调用该方法,首先将参数封装成 {@link PropertyTokenizer} 并
   *     赋值到(变量prop,prop={name='order',index='0',children='name'})中,再调用
   *     {@link PropertyTokenizer#hasNext()} 得到true,再调用
   *     {@link PropertyTokenizer#getIndexedName()}得到'order[0]',再用'order[0]'调用
   *     {@link MetaObject#metaObjectForProperty(String)}得到封装着 对应'order'的类中属性对象
   *     的{@link MetaObject} 并赋值给metaValue,然后判断metaValue是否等于{@link SystemMetaObject#NULL_META_OBJECT},
   *     是就返回null,如果不是,就调用 {@link PropertyTokenizer#getChildren()} 得到 'name',在用'name'作为
   *     参数递归调用 {@link MetaObject#getValue(String)},这时以'name'为参数传进来,会将'name'封装成
   *     {@link PropertyTokenizer} 赋值给(变量prop,prop={name='name',index=null,children=null}),
   *     此时,{@link PropertyTokenizer#hasNext()}得到false,调用 {@link ObjectWrapper#get(PropertyTokenizer)}。
   * </p>
   */
  public Object getValue(String name) {
    PropertyTokenizer prop = new PropertyTokenizer(name);
    if (prop.hasNext()) {//存在下一级属性
      MetaObject metaValue = metaObjectForProperty(prop.getIndexedName());
      if (metaValue == SystemMetaObject.NULL_META_OBJECT) {
        return null;
      } else {
        return metaValue.getValue(prop.getChildren());
      }
    } else {
      return objectWrapper.get(prop);
    }
  }

  /**
   * 判断PropertyTokenizer(参数name)是否还存在下一级,如果存在递归该方法,指定找到最后一个对象,对其赋上(参数value)的值。
   * 最后是通过 {@link ObjectWrapper#set(PropertyTokenizer, Object)} 对对应于(参数name)的对象赋上(参数value)的值。
   * <p>
   *     例:<br/>
   *     以(参数name='order[0].name')调用该方法,首先将参数封装成 {@link PropertyTokenizer} 并
   *     赋值到(变量prop,prop={name='order',index='0',children='name'})中,再调用
   *     {@link PropertyTokenizer#hasNext()} 得到true,再调用
   *     {@link PropertyTokenizer#getIndexedName()}得到'order[0]',再用'order[0]'调用
   *     {@link MetaObject#metaObjectForProperty(String)}得到封装着 对应'order'的类中属性对象
   *     的{@link MetaObject} 并赋值给metaValue,然后判断metaValue是否等于{@link SystemMetaObject#NULL_META_OBJECT},
   *     是就直接结束该方法,如果不是,调用
   * </p>
   */
  public void setValue(String name, Object value) {
    PropertyTokenizer prop = new PropertyTokenizer(name);
    if (prop.hasNext()) {
      MetaObject metaValue = metaObjectForProperty(prop.getIndexedName());
      if (metaValue == SystemMetaObject.NULL_META_OBJECT) {
        if (value == null) {
          // don't instantiate child path if value is null
          return;
        } else {
          metaValue = objectWrapper.instantiatePropertyValue(name, prop, objectFactory);
        }
      }
      metaValue.setValue(prop.getChildren(), value);
    } else {
      objectWrapper.set(prop, value);
    }
  }

  /**
   * 获取封装 Object的参数name的属性对象 的 {@link MetaObject}
   * <p>
   *  以参数name调用 {@link MetaObject#getValue} 拿到Object中的(参数name)属性对象并赋值给变量value,
   *  然后将value封装成 {@link MetaObject} 对象返回出去
   * </p>
   */
  public MetaObject metaObjectForProperty(String name) {
    Object value = getValue(name);
    return MetaObject.forObject(value, objectFactory, objectWrapperFactory, reflectorFactory);
  }

  public ObjectWrapper getObjectWrapper() {
    return objectWrapper;
  }

  public boolean isCollection() {
    return objectWrapper.isCollection();
  }

  public void add(Object element) {
    objectWrapper.add(element);
  }

  public <E> void addAll(List<E> list) {
    objectWrapper.addAll(list);
  }

}

PropertyTokenizer

/**
 *    Copyright 2009-2017 the original author or authors.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */
package org.apache.ibatis.reflection.property;

import java.util.Iterator;

/**
 * 字符串表达式解析封装类
 * <br/>
 * <ul>
 *  <li>'orders[0].items[0].name' -> name=orders,indexName='orders[0]',index='0'(orders后面那个0),children='items[0].name'</li>
 *  <li>'item[0].name' -> name='item',indexName='item[0]',index='0'(index后面那个0),children='name'</li>
 *  <li>'name' -> name='name' ,indexName='name',index=null,children=null</li>
 * </ul>
 * @author Clinton Begin
 */
public class PropertyTokenizer implements Iterator<PropertyTokenizer> {
  /**
   * 表达式名称
   */
  private String name;
  /**
   * 表达式的索引序名称
   */
  private final String indexedName;
  /**
   * 索引下标
   */
  private String index;
  /**
   * 子表达式
   */
  private final String children;

  /**
   * 传入要解析的字符串表达式,例如“orders[0].items[0].name”
   */
  public PropertyTokenizer(String fullname) {
    int delim = fullname.indexOf('.');
    if (delim > -1) {
      name = fullname.substring(0, delim);//name= orders[0]
      children = fullname.substring(delim + 1);//children= items[0].name
    } else {
      name = fullname;
      children = null;
    }
    indexedName = name; //indexName=orders[0]
    delim = name.indexOf('[');
    if (delim > -1) {
      index = name.substring(delim + 1, name.length() - 1);//orders[0]=>0
      name = name.substring(0, delim);//order
    }
  }

  /**
   * orders[0].items[0].name==>order
   * @return
   */
  public String getName() {
    return name;
  }

  /**
   * orders[0].items[0].name==>0(order后面那个0)
   * @return
   */
  public String getIndex() {
    return index;
  }

  /**
   * orders[0].items[0].name==>orders[0]
   * @return
   */
  public String getIndexedName() {
    return indexedName;
  }

  /**
   * <ul>
   *     <li>orders[0].items[0].name==>items[0].name</li>
   *     <li>orders[0].name==>name</li>
   * </ul>
   */
  public String getChildren() {
    return children;
  }

  /**
   *  如'orders[0].items[0].name',其children就是items[0].name,如果children不为null返回true
   * @return
   */
  @Override
  public boolean hasNext() {
    return children != null;
  }

  /**
   * 创建新的PropertyTokenizer对象并解析children字段子表达式
   */
  @Override
  public PropertyTokenizer next() {
    return new PropertyTokenizer(children);
  }

  @Override
  public void remove() {
    throw new UnsupportedOperationException("Remove is not supported, as it has no meaning in the context of properties.");
  }
}

SystemMetaObject

/**
 *    Copyright 2009-2015 the original author or authors.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */
package org.apache.ibatis.reflection;

import org.apache.ibatis.reflection.factory.DefaultObjectFactory;
import org.apache.ibatis.reflection.factory.ObjectFactory;
import org.apache.ibatis.reflection.wrapper.DefaultObjectWrapperFactory;
import org.apache.ibatis.reflection.wrapper.ObjectWrapperFactory;

/**
 * Mybatis的系统化MetaObject
 * <p>
 *     主要是为了方便构造 {@link MetaObject},里面声明了默认的{@link ObjectFactory},{@link ObjectWrapperFactory
 *     对应 null 的 {@link MetaObject} ,以及构造{@link MetaObject}的简便方法
 * </p>
 * @author Clinton Begin
 */
public final class SystemMetaObject {

  /**
   * {@link DefaultObjectFactory}
   */
  public static final ObjectFactory DEFAULT_OBJECT_FACTORY = new DefaultObjectFactory();
  /**
   * {@link DefaultObjectWrapperFactory}
   */
  public static final ObjectWrapperFactory DEFAULT_OBJECT_WRAPPER_FACTORY = new DefaultObjectWrapperFactory();
  /**
   * 表示是个空对象
   */
  public static final MetaObject NULL_META_OBJECT = MetaObject.forObject(NullObject.class, DEFAULT_OBJECT_FACTORY, DEFAULT_OBJECT_WRAPPER_FACTORY, new DefaultReflectorFactory());

  private SystemMetaObject() {
    // Prevent Instantiation of Static Class
  }

  private static class NullObject {
  }

  /**
   * 直接调用{@link MetaObject#forObject(Object, ObjectFactory, ObjectWrapperFactory, ReflectorFactory)}
   * <p>
   *     将(参数object),{@link SystemMetaObject#DEFAULT_OBJECT_FACTORY},{@link SystemMetaObject#DEFAULT_OBJECT_WRAPPER_FACTORY},
   *
   * </p>
   * @param object
   * @return
   */
  public static MetaObject forObject(Object object) {
    return MetaObject.forObject(object, DEFAULT_OBJECT_FACTORY, DEFAULT_OBJECT_WRAPPER_FACTORY, new DefaultReflectorFactory());
  }

}

MetaClass

/**
 *    Copyright 2009-2018 the original author or authors.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */
package org.apache.ibatis.reflection;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Collection;

import org.apache.ibatis.reflection.invoker.GetFieldInvoker;
import org.apache.ibatis.reflection.invoker.Invoker;
import org.apache.ibatis.reflection.invoker.MethodInvoker;
import org.apache.ibatis.reflection.property.PropertyTokenizer;

/**
 * 元类
 *
 * <p>
 *    MetaClass是mybatis用于简化反射操作的封装类。只是对类附加一下更加便捷描述的功能,Meta一般表示对一个东西的描述信息
 * </p>
 * @author Clinton Begin
 */
public class MetaClass {

  /**
   * 当前类的 {@link ReflectorFactory}
   */
  private final ReflectorFactory reflectorFactory;

  /**
   * 当前类的 {@link Reflector}
   */
  private final Reflector reflector;

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

  public static MetaClass forClass(Class<?> type, ReflectorFactory reflectorFactory) {
    return new MetaClass(type, reflectorFactory);
  }

  /**
   * 在reflector中取出参数name的getter方法的返回类型propType,再将propType封装成MetaClass返回出去(装饰者模式)
   */
  public MetaClass metaClassForProperty(String name) {
    Class<?> propType = reflector.getGetterType(name);
    return MetaClass.forClass(propType, reflectorFactory);
  }

  /**
   * 获取属性,以参数name='Order[0].Name'调用该方法,会从先查找类中是否有'Order'对应的属性order,
   * 找到之后,再找order属性getter方法的返回类型封装成MetaClass,在查找看看有没有'Name'对应的name属性,
   * 最后该方法返回'order.name'
   */
  public String findProperty(String name) {
    StringBuilder prop = buildProperty(name, new StringBuilder());
    return prop.length() > 0 ? prop.toString() : null;
  }

  /**
   * 查找属性,useCamelCaseMapping=true时,假设name='O_r_der'时,就会变成'order',
   * 最后还是调用{@link MetaClass#findProperty(String)}
   * @param useCamelCaseMapping 使用驼峰式大小写映射,会将name中的下划线字符全部改成空字符串
   * @return
   */
  public String findProperty(String name, boolean useCamelCaseMapping) {
    if (useCamelCaseMapping) {
      name = name.replace("_", "");
    }
    return findProperty(name);
  }

  /**
   *
   * 实际直接调用 {@link Reflector#getGetablePropertyNames()}
   * @return
   */
  public String[] getGetterNames() {
    return reflector.getGetablePropertyNames();
  }

  /**
   * 实际直接调用 {@link Reflector#getSetablePropertyNames()}
   * @return
   */
  public String[] getSetterNames() {
    return reflector.getSetablePropertyNames();
  }

  /**
   * 返回对应(参数name)类中属性的setter方法的参数类型,最终调用 {@link Reflector#getSetterType(String)}获取
   * <p>
   *     以参数名name='order[0].name'为例执行该方法:将name封装PropertyTokenizer(name='order',index='0',childer='name')
   *     并赋值给prop变量,调用(变量prop)的 {@link PropertyTokenizer#hasNext()} 得到true,将 从(变量prop)中调用 {@link PropertyTokenizer#getName()}
   *     得到'order' 传入 {@link MetaClass#metaClassForProperty(String)}得到对应'order'的类中属性的 {@link MetaClass} 并
   *     赋值给(变量metaProp),再将 从(变量prop)调用{@link PropertyTokenizer#getChildren()}得到'name' 传入
   *     (变量metaProp)的 {@link MetaClass#getSetterType(String)}:将'name' 封装成 {@link PropertyTokenizer} 并赋值给
   *     (变量prop,prop={name='name',index=null,children=null}),调用(变量prop)的 {@link PropertyTokenizer#hasNext()}
   *     得到false,最终调用 {@link Reflector#getSetterType(String)} 获取对应'name'的类中属性的setter的参数类型
   * </p>
   *
   */
  public Class<?> getSetterType(String name) {
    PropertyTokenizer prop = new PropertyTokenizer(name);
    if (prop.hasNext()) {
      MetaClass metaProp = metaClassForProperty(prop.getName());
      return metaProp.getSetterType(prop.getChildren());
    } else {
      return reflector.getSetterType(prop.getName());
    }
  }

  /**
   * 返回对应(参数name)类中属性的getter方法的参数类型,最终调用 {@link Reflector#getGetterType(String)}}获取
   * <p>
   *     以参数名name='order[0].name'为例执行该方法:将name封装PropertyTokenizer(name='order',index='0',childer='name')
   *     并赋值给prop变量,调用(变量prop)的 {@link PropertyTokenizer#hasNext()} 得到true,将 从(变量prop)中调用 {@link PropertyTokenizer#getName()}
   *     得到'order' 传入 {@link MetaClass#metaClassForProperty(String)}得到对应'order'的类中属性的 {@link MetaClass} 并
   *     赋值给(变量metaProp),再将 从(变量prop)调用{@link PropertyTokenizer#getChildren()}得到'name' 传入
   *     (变量metaProp)的 {@link MetaClass#getGetterType(String)}:将'name' 封装成 {@link PropertyTokenizer} 并赋值给
   *     (变量prop,prop={name='name',index=null,children=null}),调用(变量prop)的 {@link PropertyTokenizer#hasNext()}
   *     得到false,最终调用 {@link Reflector#getGetterType(String)} 获取对应'name'的类中属性的setter的参数类型
   * </p>
   *
   */
  public Class<?> getGetterType(String name) {
    PropertyTokenizer prop = new PropertyTokenizer(name);
    if (prop.hasNext()) {
      MetaClass metaProp = metaClassForProperty(prop);
      return metaProp.getGetterType(prop.getChildren());
    }
    // issue #506. Resolve the type inside a Collection Object
    return getGetterType(prop);
  }

  /**
   * 获取对应(参数prop)的属性的 {@link MetaClass}
   * <p>
   *     调用 {@link MetaClass#getGetterType(PropertyTokenizer)} 得到 对应(参数prop)的属性的类型并赋值给
   *     (变量propType),再将(变量propType)和(成员变量reflectorFactory)传入 {@link MetaClass#forClass(Class, ReflectorFactory)}
   *     得到 {@link MetaClass} 返回出去
   * </p>
   */
  private MetaClass metaClassForProperty(PropertyTokenizer prop) {
    Class<?> propType = getGetterType(prop);
    return MetaClass.forClass(propType, reflectorFactory);
  }

  /**
   * 获取参数prop的getter方法的返回类型:
   * <p>
   *     例:<br/>
   *     以'order[0].name'作为参数prop调用该方法,(p:prop={name='order',index='0',children='name'}),
   *     以prop.getName()='order'调用 {@link Reflector#getGetterType(String)} 得到类中'order'属性的
   *     getter方法返回类型赋值给type。在判断prop.index是否有值以及type是否属于集合类型。如果条件满足,将
   *     prop.getName()='order'作为参数调用 {@link MetaClass#getGenericGetterType(String)} 获取属性
   *     getter方法的返回类型,并赋值给returnType变量。假设,returnType是一个泛型ParameterizeType,就会
   *     通过 {@link ParameterizedType#getActualTypeArguments()} 得到声明的类型,并赋值给actualTypeArguments
   *     变量,判断actualTypeArgument的数组长度是否只有一个(方法的返回类型肯定是只有一个,所以一定为true),再取出
   *     actualTypeArguments的第一个元素并赋值给returnType变量,再判断returnType是泛型还是普通java类,如果是普通
   *     java类型,就直接返回出去,如果是泛型,就返回泛型中<>前面的那个类
   * </p>
   */
  private Class<?> getGetterType(PropertyTokenizer prop) {
    Class<?> type = reflector.getGetterType(prop.getName());
    if (prop.getIndex() != null && Collection.class.isAssignableFrom(type)) {
      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) {
            type = (Class<?>) ((ParameterizedType) returnType).getRawType();
          }
        }
      }
    }
    return type;
  }

  /**
   * 获取通用Getter方法返回类型,捕捉了反射的相关异常,找不到propertyName的执行器就会返回null
   */
  private Type getGenericGetterType(String propertyName) {
    try {
      Invoker invoker = reflector.getGetInvoker(propertyName);//拿到的Invoker
      if (invoker instanceof MethodInvoker) {//方法getter执行器
        Field _method = MethodInvoker.class.getDeclaredField("method");
        _method.setAccessible(true);
        Method method = (Method) _method.get(invoker);
        return TypeParameterResolver.resolveReturnType(method, reflector.getType());
      } else if (invoker instanceof GetFieldInvoker) {//属性getter执行器
        Field _field = GetFieldInvoker.class.getDeclaredField("field");
        _field.setAccessible(true);
        Field field = (Field) _field.get(invoker);
        return TypeParameterResolver.resolveFieldType(field, reflector.getType());
      }
    } catch (NoSuchFieldException | IllegalAccessException ignored) {
    }
    return null;
  }

  /**
   * 判断是否存在对应(参数name)的属性的setter方法,找出对应(参数name)的属性,最终调用
   * {@link Reflector#hasSetter(String)} 判断。
   * <p>
   *    将(参数name='order[0].name')传入该方法,将(参数name)包装成 {@link PropertyTokenizer} 并
   *    赋值给(变量prop,prop={name='order',index='0',children='name'),调用(变量prop)的
   *    {@link PropertyTokenizer#hasNext()}得到true,将 从(变量prop)的调用{@link PropertyTokenizer#getName()}
   *    得到'order'传入{@link Reflector#hasSetter(String)}得到true,再将 从(变量prop)的调用 {@link PropertyTokenizer#getName()}
   *    得到'order' 调用 {@link MetaClass#metaClassForProperty(String)}得到对应'order'的属性的 {@link MetaClass},再
   *    将 从(变量prop)的 {@link PropertyTokenizer#getChildren()}得到'name'传入 {@link MetaClass#hasSetter(String)}:
   *    将'name'包装成 {@link PropertyTokenizer} 并赋值给(变量prop,prop={name='name',index=null,children=null),调用(变量prop)
   *    的 {@link PropertyTokenizer#hasNext()} 得到false,调用 {@link Reflector#hasSetter(String)}
   * </p>
   */
  public boolean hasSetter(String name) {
    PropertyTokenizer prop = new PropertyTokenizer(name);
    if (prop.hasNext()) {
      if (reflector.hasSetter(prop.getName())) {
        MetaClass metaProp = metaClassForProperty(prop.getName());
        return metaProp.hasSetter(prop.getChildren());
      } else {
        return false;
      }
    } else {
      return reflector.hasSetter(prop.getName());
    }
  }

  /**
   * 判断是否存在对应(参数name)的属性的getter方法,找出对应(参数name)的属性,最终调用
   * {@link Reflector#hasSetter(String)} 判断。
   * <p>
   *    将(参数name='order[0].name')传入该方法,将(参数name)包装成 {@link PropertyTokenizer} 并
   *    赋值给(变量prop,prop={name='order',index='0',children='name'),调用(变量prop)的
   *    {@link PropertyTokenizer#hasNext()}得到true,将 从(变量prop)的调用{@link PropertyTokenizer#getName()}
   *    得到'order'传入{@link Reflector#hasGetter(String)}得到true,再将 从(变量prop)的调用 {@link PropertyTokenizer#getName()}
   *    得到'order' 调用 {@link MetaClass#metaClassForProperty(String)}得到对应'order'的属性的 {@link MetaClass},再
   *    将 从(变量prop)的 {@link PropertyTokenizer#getChildren()}得到'name'传入 {@link MetaClass#hasGetter(String)}:
   *    将'name'包装成 {@link PropertyTokenizer} 并赋值给(变量prop,prop={name='name',index=null,children=null),调用(变量prop)
   *    的 {@link PropertyTokenizer#hasNext()} 得到false,调用 {@link Reflector#hasGetter(String)} 判断
   * </p>
   */
  public boolean hasGetter(String name) {
    PropertyTokenizer prop = new PropertyTokenizer(name);
    if (prop.hasNext()) {
      if (reflector.hasGetter(prop.getName())) {
        MetaClass metaProp = metaClassForProperty(prop);
        return metaProp.hasGetter(prop.getChildren());
      } else {
        return false;
      }
    } else {
      return reflector.hasGetter(prop.getName());
    }
  }

  /**
   * 直接调用{@link Reflector#getGetInvoker(String)}
   */
  public Invoker getGetInvoker(String name) {
    return reflector.getGetInvoker(name);
  }

  /**
   * 直接调用{@link Reflector#getSetInvoker(String)}
   */
  public Invoker getSetInvoker(String name) {
    return reflector.getSetInvoker(name);
  }

  /**
   * 以name='Order[0].Name',builder=''作为参数调用:</br/>
   * 代码中:prop:{name='Order',index='0',children='Name'},prop.hashNext=true,通过reflector查找出对应的
   * 属性名order赋值到propertyName变量中,若找到则propertyName!=null,builder='order.',
   * 再调用metaClassForPropety(propertyName)得到propertyName的MetaClass赋值给metaProp,再调用
   * metaProp.buildProperty(prop.getChildren(),builder)方法,
   * 此时prop.getChildren()='name',builder='order.name'
   * metaProp.buildProperty(prop.getChildren(),builder)方法会返回'order.name'.
   *
   */
  private StringBuilder buildProperty(String name, StringBuilder builder) {
    PropertyTokenizer prop = new PropertyTokenizer(name);
    if (prop.hasNext()) {
      String propertyName = reflector.findPropertyName(prop.getName());
      if (propertyName != null) {
        builder.append(propertyName);
        builder.append(".");
        MetaClass metaProp = metaClassForProperty(propertyName);
        metaProp.buildProperty(prop.getChildren(), builder);
      }
    } else {
      String propertyName = reflector.findPropertyName(name);
      if (propertyName != null) {
        builder.append(propertyName);
      }
    }
    return builder;
  }

  /**
   * 直接调用 {@link Reflector#hasDefaultConstructor()}
   * @return
   */
  public boolean hasDefaultConstructor() {
    return reflector.hasDefaultConstructor();
  }

}

TypeParameterResolver

/**
 *    Copyright 2009-2019 the original author or authors.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */
package org.apache.ibatis.reflection;

import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.lang.reflect.WildcardType;
import java.util.Arrays;

/**
 * 主要解决泛型,内嵌套时的 方法或者属性 获取类型问题
 * @author Iwao AVE!
 */
public class TypeParameterResolver {

  /**
   *  解析获取field在srcType中的返回类型
   * @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);
  }

  /**
   * 解析获取method在srcType中的返回类型
   * @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.
   */
  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++) {
      result[i] = resolveType(paramTypes[i], srcType, declaringClass);
    }
    return result;
  }

  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) {//ParameterizedType通常发生在集合的泛型使用
      return resolveParameterizedType((ParameterizedType) type, srcType, declaringClass);
    } else if (type instanceof GenericArrayType) {//泛型数组
      return resolveGenericArrayType((GenericArrayType) type, srcType, declaringClass);
    } else {
      return type;
    }
  }

  /**
   * 解析数组类型
   */
  private static Type resolveGenericArrayType(GenericArrayType genericArrayType, Type srcType, Class<?> declaringClass) {
    Type componentType = genericArrayType.getGenericComponentType();//获取数组类型的元素类型
    Type resolvedComponentType = null;
    if (componentType instanceof TypeVariable) {
      resolvedComponentType = resolveTypeVar((TypeVariable<?>) componentType, srcType, declaringClass);
    } else if (componentType instanceof GenericArrayType) {
      resolvedComponentType = resolveGenericArrayType((GenericArrayType) componentType, srcType, declaringClass);
    } else if (componentType instanceof ParameterizedType) {
      resolvedComponentType = resolveParameterizedType((ParameterizedType) componentType, srcType, declaringClass);
    }
    if (resolvedComponentType instanceof Class) {
      return Array.newInstance((Class<?>) resolvedComponentType, 0).getClass();
    } else {
      return new GenericArrayTypeImpl(resolvedComponentType);
    }
  }

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

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


  private static Type resolveTypeVar(TypeVariable<?> typeVar, Type srcType, Class<?> declaringClass) {
    Type result;
    Class<?> clazz;//引入类
    if (srcType instanceof Class) {//普通java类型
      clazz = (Class<?>) srcType;
    } else if (srcType instanceof ParameterizedType) {//泛型类
      ParameterizedType parameterizedType = (ParameterizedType) srcType;
      clazz = (Class<?>) parameterizedType.getRawType();
    } else {
      //srcType是否为普通java类又不是泛型,抛出异常也是很正常的
      throw new IllegalArgumentException("The 2nd arg must be Class or ParameterizedType, but was: " + srcType.getClass());
    }

    //如果declaringClass和srcType的类型一致的情况下,是无法获取其类型实参类型的
    //这个时候如果有类型变量,取第一个,否则取Object
    if (clazz == declaringClass) {
      //TypeVariable.getBounds()获得该类型变量的上限,也就是泛型中extend右边,
      // 如  class binTest<T extends Number & Serializable & Comparable> => Number,Serializable,Comparable
      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;
  }

  /**
   * 扫描超类
   */
  private static Type scanSuperTypes(TypeVariable<?> typeVar, Type srcType, Class<?> declaringClass, Class<?> clazz, Type superclass) {
    if (superclass instanceof ParameterizedType) {// binTest<T> 像这种类都会继承ParameterizedType接口
      ParameterizedType parentAsType = (ParameterizedType) superclass;
      //获取声明泛型的类或者接口,也就是泛型中<>前面的那个值,如binTest<T> =>binTest
      Class<?> parentAsClass = (Class<?>) parentAsType.getRawType();
      //返回一个代表该泛型声明中声明的类型变量TypeVariable对象的数组,如binTest<T,E> => T,E
      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) {
    //getActualTypeArguments返回了一个Type数组,数组里是参数化类型的参数,如Map<String,Long> =>String,Long
    Type[] parentTypeArgs = parentType.getActualTypeArguments();
    Type[] srcTypeArgs = srcType.getActualTypeArguments();
    //返回一个代表该泛型声明中声明的类型变量TypeVariable对象的数组,如binTest<T,E> => T,E
    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();
  }

  static class ParameterizedTypeImpl implements ParameterizedType {
    private Class<?> rawType;

    private Type ownerType;

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容