反射工具箱-工具类

ObjectFactory

创建对象使用的工厂接口

public interface ObjectFactory {

  /**
   * Sets configuration properties.
   * @param properties configuration properties
   */
  default void setProperties(Properties properties) {
    // NOP
    //No Operation Performed 无操作执行
  }

  /**
   * 使用默认构造方法创建对象
   * Creates a new object with default constructor.
   * @param type Object type
   * @return
   */
   T create(Class type);

  /**
   * 使用特定参数的构造方法创建对象
   * Creates a new object with the specified constructor and params.
   * @param type Object type
   * @param constructorArgTypes Constructor argument types
   * @param constructorArgs Constructor argument values
   * @return
   */
   T create(Class type, List> constructorArgTypes, List constructorArgs);

  /**
   * 检测指定类型是否为集合类型,主妥处理 java.util.Collection 及其子类
   * Returns true if this object can have a set of other objects.
   * It's main purpose is to support non-java.util.Collection objects like Scala collections.
   *
   * @param type Object type
   * @return whether it is a collection or not
   * @since 3.1.0
   */
   boolean isCollection(Class type);

}
 
 

DefaultObjectFactory

默认创建对象的工厂实现,使用 Java 反射技术

public class DefaultObjectFactory implements ObjectFactory, Serializable {

  private static final long serialVersionUID = -8855120656740914948L;

  @Override
  public  T create(Class type) {
    return create(type, null, null);
  }

  @SuppressWarnings("unchecked")
  @Override
  public  T create(Class type, List> constructorArgTypes, List constructorArgs) {
    // 解决集合接口,解决接口默认实现类
    Class classToCreate = resolveInterface(type);
    // we know types are assignable
    return (T) instantiateClass(classToCreate, constructorArgTypes, constructorArgs);
  }

  //创造对象
  private   T instantiateClass(Class type, List> constructorArgTypes, List constructorArgs) {
    try {
      Constructor constructor;
      //无参构造函数
      if (constructorArgTypes == null || constructorArgs == null) {
        constructor = type.getDeclaredConstructor();
        try {
          return constructor.newInstance();
        } catch (IllegalAccessException e) {
          //查看是否能控制成员的访问,能设置true,访问
          if (Reflector.canControlMemberAccessible()) {
            constructor.setAccessible(true);
            return constructor.newInstance();
          } else {
            throw e;
          }
        }
      }
      //根据参数得到对应的构造方法
      constructor = type.getDeclaredConstructor(constructorArgTypes.toArray(new Class[constructorArgTypes.size()]));
      try {
        //构造对象实例
        return constructor.newInstance(constructorArgs.toArray(new Object[constructorArgs.size()]));
      } catch (IllegalAccessException e) {
        if (Reflector.canControlMemberAccessible()) {
          constructor.setAccessible(true);
          return constructor.newInstance(constructorArgs.toArray(new Object[constructorArgs.size()]));
        } else {
          throw e;
        }
      }
    } catch (Exception e) {
      String argTypes = Optional.ofNullable(constructorArgTypes).orElseGet(Collections::emptyList)
          .stream().map(Class::getSimpleName).collect(Collectors.joining(","));
      String argValues = Optional.ofNullable(constructorArgs).orElseGet(Collections::emptyList)
          .stream().map(String::valueOf).collect(Collectors.joining(","));
      throw new ReflectionException("Error instantiating " + type + " with invalid types (" + argTypes + ") or values (" + argValues + "). Cause: " + e, e);
    }
  }
  /**
   * 解决集合接口,解决接口默认实现类
   */
  protected Class resolveInterface(Class type) {
    Class classToCreate;
    if (type == List.class || type == Collection.class || type == Iterable.class) {
      classToCreate = ArrayList.class;
    } else if (type == Map.class) {
      classToCreate = HashMap.class;
    } else if (type == SortedSet.class) { // issue #510 Collections Support
      classToCreate = TreeSet.class;
    } else if (type == Set.class) {
      classToCreate = HashSet.class;
    } else {
      //first:TreeMap is this type;maybe mybatis is not support the type;(only my guess)
      //second: other original type:like java bean;String;
      classToCreate = type;
    }
    return classToCreate;
  }

  @Override
  public  boolean isCollection(Class type) {
    return Collection.class.isAssignableFrom(type);
  }

}
 
 

ExampleObjectFactory

对象工厂的样例,样可以在 mybatis-config.xml 对象中指定创建对象的工厂。

public class ExampleObjectFactory extends DefaultObjectFactory {
  private Properties properties;

  @Override
  public  T create(Class type) {
    return super. create(type);
  }

  @Override
  public  T create(Class type, List> constructorArgTypes, List constructorArgs) {
    return super. create(type, constructorArgTypes, constructorArgs);
  }

  @Override
  public void setProperties(Properties properties) {
    super.setProperties(properties);
    this.properties = properties;
  }

  public Properties getProperties() {
    return properties;
  }

}
 
 

Property 工具集

反射模块中使用到的三个属性工具类,分别是 PropertyTokenizer
PropertyNamer 和 PropertyCopier。

PropertyTokenizer

PropertyTokenizer是分词器,编译器,解析这样的 orders[0].items[0].name 表达式,实现了Iterator,具有迭代功能

public class PropertyTokenizer implements Iterator {
//  orders[0].items[0].name 第一次迭代
  private String name; //当前表达式的名称 orders
  private final String indexedName; //当前表达式的索引名  orders[0]
  private String index; //索引下标 0
  private final String children; //子表达式 items[0].name

  public PropertyTokenizer(String fullname) {
    int delim = fullname.indexOf('.');
    if (delim > -1) {
      name = fullname.substring(0, delim);
      children = fullname.substring(delim + 1);
    } else {
      name = fullname;
      children = null;
    }
    indexedName = name;
    delim = name.indexOf('[');
    if (delim > -1) {
      index = name.substring(delim + 1, name.length() - 1);
      name = name.substring(0, delim);
    }
  }

  public String getName() {
    return name;
  }

  public String getIndex() {
    return index;
  }

  public String getIndexedName() {
    return indexedName;
  }

  public String getChildren() {
    return children;
  }

  @Override
  public boolean hasNext() {
    return children != null;
  }

  @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.");
  }
}

用例

PropertyTokenizer 继承了 Iterator 接口,它可以法代处理嵌套多层表达式。PropertyTokenizer.next() 方法中会创建新的 PropertyTokenize 对象并解析 children 宇段记录的子表达式。为了便于读者理解,这里继续使用前面的订单示例进行说明,描述解析属性表达式
orders[O].items[O].name 的迭代过程。


image.png

PropertyNamer

获取类的 getter、setter 方法 对应的属性名称。
工具类 getter 和 setter 属性的处理方法;

public final class PropertyNamer {

  private PropertyNamer() {
    // Prevent Instantiation of Static Class
  }
  //getId -> id;根据get和set方法;返回属性
  public static String methodToProperty(String name) {
    if (name.startsWith("is")) {
      name = name.substring(2);
    } else if (name.startsWith("get") || name.startsWith("set")) {
      name = name.substring(3);
    } else {
      throw new ReflectionException("Error parsing property name '" + name + "'.  Didn't start with 'is', 'get' or 'set'.");
    }
    //作用 Id --> id;
    if (name.length() == 1 || (name.length() > 1 && !Character.isUpperCase(name.charAt(1)))) {
      name = name.substring(0, 1).toLowerCase(Locale.ENGLISH) + name.substring(1);
    }

    return name;
  }
  // 是否是一个类的 getter 和 setter 方法
  public static boolean isProperty(String name) {
    return isGetter(name) || isSetter(name);
  }
  //是否包含 get方法 和 is方法
  public static boolean isGetter(String name) {
    return (name.startsWith("get") && name.length() > 3) || (name.startsWith("is") && name.length() > 2);
  }
  //是否包含 set方法
  public static boolean isSetter(String name) {
    return name.startsWith("set") && name.length() > 3;
  }

}

PropertyCopier

PropertyCopier 一个属性拷贝的工具类,主要处理相同类型的两个对象之间的属性拷贝。

public final class PropertyCopier {

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

  /**
   * 主要处理相同类型的两个对象之间的属性拷贝
   * @param type
   * @param sourceBean 原对象
   * @param destinationBean 目标对象
   */
  public static void copyBeanProperties(Class type, Object sourceBean, Object destinationBean) {
    Class parent = type;
    while (parent != null) {
      final Field[] fields = parent.getDeclaredFields();
      for (Field field : fields) {
        try {
          try {
            field.set(destinationBean, field.get(sourceBean));
          } catch (IllegalAccessException e) {
            if (Reflector.canControlMemberAccessible()) {
              field.setAccessible(true);
              field.set(destinationBean, field.get(sourceBean));
            } else {
              throw e;
            }
          }
        } catch (Exception e) {
          // Nothing useful to do, will only fail on final fields, which will be ignored.
        }
      }
      parent = parent.getSuperclass();
    }
  }

}

MetaClass

MetaClass 是对 Reflector 的封装,是类层次的信息封装。
MetaClass 通过 Reflector 和 PropertyTokenizer 组合使用, 实现了对复杂的属性表达式的解析,并实现了获取指定属性描述信息的功能。
主要实现了 1.检测是否包含这个复杂的属性表达式,2.属性表达式的返回数据类型 3.返回 Reflector 对象的集合信息们。

public class MetaClass {
  //ReflectorFactory 对象,用于缓存 Reflector 对象
  private final ReflectorFactory reflectorFactory;
  //在创建 MetaClass 时会指定一个类,该 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);
  }
  /**
   * 根据属性名字,创建这个属性 数据类型的 MetaClass 对象
   */
  public MetaClass metaClassForProperty(String name) {
    Class propType = reflector.getGetterType(name);
    return MetaClass.forClass(propType, reflectorFactory);
  }

  /**
   * 查找是否有相应的 name(user.address.country) 复杂属性表达式,并返回;只进行了 . 这样复杂属性的导航,并没有对下表进行解析
   * @param name
   * @return
   */
  public String findProperty(String name) {
    // 构建的属性信息 user.address.country
    StringBuilder prop = buildProperty(name, new StringBuilder());
    return prop.length() > 0 ? prop.toString() : null;
  }

  /**
   * 查找是否有相应的 name 属性表达式,并返回
   * @param name
   * @param useCamelCaseMapping 第二个参数表示是否忽略属性表达式中的下画线
   * @return
   */
  public String findProperty(String name, boolean useCamelCaseMapping) {
    if (useCamelCaseMapping) {
      name = name.replace("_", "");
    }
    return findProperty(name);
  }

  /**
   * 获取类的可读属性们
   * @return
   */
  public String[] getGetterNames() {
    return reflector.getGetablePropertyNames();
  }
  /**
   * 获取类的可写属性们
   * @return
   */
  public String[] getSetterNames() {
    return reflector.getSetablePropertyNames();
  }

  /**
   * 获取属性表达式的数据类型
   * @param name
   * @return
   */
  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());
    }
  }

  /**
   * 获取类字段 get 方法的返回值类型
   * @param name
   * @return
   */
  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);
  }

  /**
   * 根据包含属性表达式的 PropertyTokenizer 解析器,创建属性的 MetaClass 对象
   * @param prop
   * @return
   */
  private MetaClass metaClassForProperty(PropertyTokenizer prop) {
    Class propType = getGetterType(prop);
    return MetaClass.forClass(propType, reflectorFactory);
  }

  /**
   * 根据包含属性的 PropertyTokenizer 对象,返回属性表达式对应的数据类型
   * @param prop
   * @return
   */
  private Class getGetterType(PropertyTokenizer prop) {
    // 返回属性数据类型
    Class type = reflector.getGetterType(prop.getName());
    // 该表达式中是否使用 [] 下表,且是 Collection 子类
    if (prop.getIndex() != null && Collection.class.isAssignableFrom(type)) {
      // 通过 TypeParameterResolver 工具类解析属性的类
      Type returnType = getGenericGetterType(prop.getName());
      // 针对 ParameterizedType 进行处理,即针对泛型集合类型进行处理
      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;
  }

  /**
   *
   * @param propertyName
   * @return
   */
  private Type getGenericGetterType(String propertyName) {
    try {
      // 根据 Reflector.getMethods 集合中记录的 Invoker 实现类的类型,决定解析 getter 方法返回值类型,还是解析字段类型
      Invoker invoker = reflector.getGetInvoker(propertyName);
      if (invoker instanceof MethodInvoker) {
        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) {
        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;
  }

  /**
   * 检查被包装类的属性表达式值是否有Setter()方法
   * @param name
   * @return
   */
  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());
    }
  }
  /**
   * 检查被包装类的属性表达式值是否有 Getter()方法,比如 orders[0].id 属性表达式
   * @param name
   * @return
   */
  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());
    }
  }

  /**
   * 获取 get 字段 封装的 Invoker 对象
   * @param name
   * @return
   */
  public Invoker getGetInvoker(String name) {
    return reflector.getGetInvoker(name);
  }

  /**
   * 获取 set 字段 封装的 Invoker 对象
   * @param name
   * @return
   */
  public Invoker getSetInvoker(String name) {
    return reflector.getSetInvoker(name);
  }

  /**
   * 构建多个属性信息
   * 根据属性表达式名称,比如:user.address.country,解析递归,查找在多个类中的多个属性信息,然后拼接属性信息,返回 StringBuilder 对象
   * @param name
   * @param builder
   * @return
   */
  private StringBuilder buildProperty(String name, StringBuilder builder) {
    PropertyTokenizer prop = new PropertyTokenizer(name);
    // 判断 name 属性是否 包含 . ,即是否包含子节点
    if (prop.hasNext()) {
      // 如果包含子节点,获取父节点的属性名称
      String propertyName = reflector.findPropertyName(prop.getName());
      if (propertyName != null) {
        // 添加到 builder 中
        builder.append(propertyName);
        builder.append(".");
        // 创建这个属性数据类型的的 MetaClass 对象
        MetaClass metaProp = metaClassForProperty(propertyName);
        // 然后根据父节点的 MetaClass 对象,查找子节点的属性,进行递归查询
        metaProp.buildProperty(prop.getChildren(), builder);
      }
    } else {
      // 不包含,然后获取属性名称
      String propertyName = reflector.findPropertyName(name);
      if (propertyName != null) {
        builder.append(propertyName);
      }
    }
    return builder;
  }
  // 是否有默认的构造方法
  public boolean hasDefaultConstructor() {
    return reflector.hasDefaultConstructor();
  }

}

MetaObject

MetaObject 是对象层级的包装,对象的 getter、setter、filed、和他们的数据类型的方法。

MetaObject 是 Mybatis 提供的一个用于方便、优雅访问对象属性的对象,通过它可以简化代码、不需要 try/catch 各种 reflect 异常,同时它支持对 JavaBean、Collection、Map 三种类型对象的操作。

MetaObject 包装了 objectWrapper,从而提供了对 对象属性 的操作。

反射包的大部分类都是为 MetaObject 服务的,这个是对外暴露的对象原信息操作的接口。

服务类包括:Reflector、ReflectorFactory、MetaClass、ObjectFactory 接口和实现、Invoker 接口和实现、ObjectWrapper 接口和实现、Property 属性工具类。

包装关系:MetaObject -> ObjectWrapper -> MetaClass -> Reflector -> 元类的基础信息(filed、getter、setter 方法、读写属性、成员的数据类型、方法的调用)。

应用场景

  • 将对象中的值(parameterType所指定的对象)映射到具体的sql中

  insert into Author (id,username,password,email,bio)
  values (#{id},#{username},#{password},#{email},#{bio})

  • 将查询出来的结果填充到具体的对象属性中(由resultMap/resultType指定)

MetaObject
public class MetaObject {

  private final Object originalObject;  //原始JavaBean对象
  private final ObjectWrapper objectWrapper; //其中封装了originalObject对象
  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;
    //赋值给objectWrapper
    if (object instanceof ObjectWrapper) {
      this.objectWrapper = (ObjectWrapper) object;
    } else if (objectWrapperFactory.hasWrapperFor(object)) {
      this.objectWrapper = objectWrapperFactory.getWrapperFor(this, object);
    } else if (object instanceof Map) {
      this.objectWrapper = new MapWrapper(this, (Map) object);
    } else if (object instanceof Collection) {
      this.objectWrapper = new CollectionWrapper(this, (Collection) object);
    } else {
      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);
  }

  public String[] getGetterNames() {
    return objectWrapper.getGetterNames();
  }

  public String[] getSetterNames() {
    return objectWrapper.getSetterNames();
  }

  public Class getSetterType(String name) {
    return objectWrapper.getSetterType(name);
  }

  public Class getGetterType(String name) {
    return objectWrapper.getGetterType(name);
  }

  //判断属性表达式指定属性是 否有 setter 方法
  public boolean hasSetter(String name) {
    return objectWrapper.hasSetter(name);
  }
  //判断属性表达式指定属性是 否有 getter 方法
  public boolean hasGetter(String name) {
    return objectWrapper.hasGetter(name);
  }
  //获取对象属性
  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);
    }
  }
  //设置对象属性
  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 {
          // 为属性表达式指定的属性创建相应的MetaObject对象
          metaValue = objectWrapper.instantiatePropertyValue(name, prop, objectFactory);
        }
      }
      metaValue.setValue(prop.getChildren(), value);
    } else {
      objectWrapper.set(prop, value);
    }
  }
  //根据属性名称获得MetaObject对象
  public MetaObject metaObjectForProperty(String name) {
    Object value = getValue(name);
    return MetaObject.forObject(value, objectFactory, objectWrapperFactory, reflectorFactory);
  }

  public ObjectWrapper getObjectWrapper() {
    return objectWrapper;
  }

  /**
   * 是否是集合
   * @return
   */
  public boolean isCollection() {
    return objectWrapper.isCollection();
  }

  /**
   * 向集合中添加元素
   * @param element
   */
  public void add(Object element) {
    objectWrapper.add(element);
  }

  /**
   * 向集合中添加多个元素
   * @param list
   * @param 
   */
  public  void addAll(List list) {
    objectWrapper.addAll(list);
  }

}

你可能感兴趣的:(反射工具箱-工具类)