Mybatis Source resolve - reflection Toolbox

Reflection Toolbox

Reflector

Class Reflector a class corresponding to the object comprises:

  //对应的Class类型
  private final Class<?> type;
  //可读属性(有get方法的)名字数组
  private final String[] readablePropertyNames;
  //可写属性(有set方法的)名字数组
  private final String[] writeablePropertyNames;
  //set方法,key为属性名称,value是Invoker对象(对set方法对应的method对象的封装)
  private final Map<String, Invoker> setMethods = new HashMap<String, Invoker>();
  //get方法
  private final Map<String, Invoker> getMethods = new HashMap<String, Invoker>();
  //set方法的参数类型
  private final Map<String, Class<?>> setTypes = new HashMap<String, Class<?>>();
  //get方法的返回值类型
  private final Map<String, Class<?>> getTypes = new HashMap<String, Class<?>>();
  //默认构造器
  private Constructor<?> defaultConstructor;
  //所有属性名称,全大写形式
  private Map<String, String> caseInsensitivePropertyMap = new HashMap<String, String>();

More attributes will be filled in the constructor

  public Reflector(Class<?> clazz) {
    type = clazz;
    addDefaultConstructor(clazz);
    addGetMethods(clazz);
    addSetMethods(clazz);
    addFields(clazz);//没有set/get方法时会使用Field操作
    readablePropertyNames = getMethods.keySet().toArray(new String[getMethods.keySet().size()]);
    writeablePropertyNames = setMethods.keySet().toArray(new String[setMethods.keySet().size()]);
    for (String propName : readablePropertyNames) {
      caseInsensitivePropertyMap.put(propName.toUpperCase(Locale.ENGLISH), propName);
    }
    for (String propName : writeablePropertyNames) {
      caseInsensitivePropertyMap.put(propName.toUpperCase(Locale.ENGLISH), propName);
    }
  }
addGetMethods
  private void addGetMethods(Class<?> cls) {
    Map<String, List<Method>> conflictingGetters = new HashMap<String, List<Method>>();
    Method[] methods = getClassMethods(cls);
    for (Method method : methods) {
      if (method.getParameterTypes().length > 0) {
        continue;
      }
      String name = method.getName();
      if ((name.startsWith("get") && name.length() > 3)
          || (name.startsWith("is") && name.length() > 2)) {
        name = PropertyNamer.methodToProperty(name);
        addMethodConflict(conflictingGetters, name, method);
      }
    }
    resolveGetterConflicts(conflictingGetters);
  }

Which is shown in the flowchart in FIG.
Here Insert Picture Description

ReflectorFactory

The main object is to create and provide Reflector cache, use concurrentMap cache object, key class

TypeParamterResolver

Type interface implementation class:

  1. Class
  2. ParameterizedType: parameterized type, such asList<String>
    • Type getRawType (): returns the original type parameters of types; as List<String>return List
    • Type [] getActualTypeArguments (): returns a list of the actual type or a variable type, such as List<String>return String
    • Type getOwnerType (): Return Type affiliations; as A<T>inner class class Inner<T>type ofA<T>
  3. GenericArrayType: an array type element, and is composed of TypeVariable or ParameterizedType; asList<String>[]
    • Type getGenericComponentType (): Returns an array of elements
  4. TypeVariable: type variable reaction JVM information before compiling the generic
    • Type [] getBounds (): Get the type of the variable boundary, Object was not declared; The Test<K extends Person>upper boundary of K Persion
    • D getGenericDeclaration (): Get the type of the original variable type declaration; as Test<K extends Person>primitive types Test
    • String getName (): Gets the name when defined in the source code, Test<K extends Person>for K
  5. WildcardType: generics as a wildcard? super Integer
    • Type [] getUpperBounds (): returns the last variable paradigm
    • Type [] getLowerBounds (): returns the next variable paradigm

ObjectFactory

The factory used to create objects, the default implementation DefaultObjectFactoryof its create () call instantiateClass(), the final callConstructor.newInstance()

Property toolset

  1. PropertyTokenizerResponsible for parsing the expression, you can iterate
  2. PropertyNamerResponsible for converting method name to the property name (remove is \ set \ get the prefix and the first letter lowercase, etc.) as well as to detect whether it is set, get a method or property
  3. PropertyCopierBean same type of copy attribute values, the method of the corecopyBeanProperties()
<resultMap id = "base" type="User">
	<id column = "id" property="id"/>
	<result column = "item" property="orders[0].items[0].name"/>
</result>

As shown in FIG decomposition
Here Insert Picture Description

MetaClass

Use Reflectorand PropertyTokenizera combination of complex analytic expressions attribute
MetaClassconstructor receives a class of this class is constructed and Reflectorthe object
MetaClass.findProperty()will be called buildProperty(), ultimately through PropertyTokenizeranalysis of complex property expression
PropertyTokenizersupra analytical methods, MetaClass.hasGetter()and MetaClass.hasSetter()ultimately by Reflectorachieved

ObjectWrapper

MetaClassIs a class-level meta-information processing and packaging, ObjectWrapperpackaging of an object, the query object defines a set of attributes, attribute update method


public interface ObjectWrapper {

  Object get(PropertyTokenizer prop);

  void set(PropertyTokenizer prop, Object value);

  String findProperty(String name, boolean useCamelCaseMapping);

  String[] getGetterNames();

  String[] getSetterNames();

  Class<?> getSetterType(String name);

  Class<?> getGetterType(String name);

  boolean hasSetter(String name);

  boolean hasGetter(String name);

  MetaObject instantiatePropertyValue(String name, PropertyTokenizer prop, ObjectFactory objectFactory);
  
  boolean isCollection();
  
  void add(Object element);
  
  <E> void addAll(List<E> element);

}

As shown in FIG its successor UML
Here Insert Picture Description

BaseWrapper is an abstract class that encapsulates MetaObject objects, and provides three methods

  • getCollectionValue
  • setCollectionValue
  • resolverCollection: calls MetaObject.getValue ()

getCollectionValue will be based on the value of the index PropertyTokenizer


protected Object getCollectionValue(PropertyTokenizer prop, Object collection) {
    if (collection instanceof Map) {
      return ((Map) collection).get(prop.getIndex());
    } else {
      int i = Integer.parseInt(prop.getIndex());
      if (collection instanceof List) {
        return ((List) collection).get(i);
      } else if (collection instanceof Object[]) {
        return ((Object[]) collection)[i];
      } else if (collection instanceof char[]) {
        return ((char[]) collection)[i];
      } else if (collection instanceof boolean[]) {
        return ((boolean[]) collection)[i];
      } else if (collection instanceof byte[]) {
        return ((byte[]) collection)[i];
      } else if (collection instanceof double[]) {
        return ((double[]) collection)[i];
      } else if (collection instanceof float[]) {
        return ((float[]) collection)[i];
      } else if (collection instanceof int[]) {
        return ((int[]) collection)[i];
      } else if (collection instanceof long[]) {
        return ((long[]) collection)[i];
      } else if (collection instanceof short[]) {
        return ((short[]) collection)[i];
      } else {
        throw new ReflectionException("The '" + prop.getName() + "' property of " + collection + " is not a List or Array.");
      }
    }
  }

BeanWrapper aimed at javaBean

  public Object get(PropertyTokenizer prop) {
  //存在索引信息
    if (prop.getIndex() != null) {
    //拿到集合对象
      Object collection = resolveCollection(prop, object);
      //获取对应索引处的值
      return getCollectionValue(prop, collection);
    } else {
    //通过metaClass操作反射get方法
      return getBeanProperty(prop, object);
    }
  }

MetaObject

Complete the process of property expression parsing, the top

  //原始JavaBean对象
  private final Object originalObject;
  //JavaBean的ObjectWrapper对象
  private final ObjectWrapper objectWrapper;
  //实例化originalObject的工厂
  private final ObjectFactory objectFactory;
  private final ObjectWrapperFactory objectWrapperFactory;
  private final ReflectorFactory reflectorFactory;

MetaObject constructor creates a corresponding ObjectWrapper original objects based on object type and passed to achieve the ObjectFactory
MetaObject ObjectWrapper level and class of methods such as: hasGetter () are operated by MetaClass
object-level method such as: getValue by and with the realization of ObjectWrapper

List relations

Here Insert Picture Description

Published 98 original articles · won praise 9 · views 10000 +

Guess you like

Origin blog.csdn.net/Mutou_ren/article/details/102840195