@[TOC]

聊聊Mybatis的反射之ObjectWrapper

MetaClass

MetaClass主要是用于获取类的属性,它的构造方法中通过ReflectorFactory工厂把class封装成Reflector

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

MetaClass的findProperty()就是获取属性的方法,另外它还有判断这个属性有没有getter setter方法的功能:

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

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

通过源码我们知道,这两个方法主要依赖于PropertyTokenizer来进行解析。

ObjectWrapper

ObjectWrapper是用来封装对象元信息的接口

CollectionWrapper

CollectionWrapper实现ObjectWrapper接口,实现了add(),addAll()和isCollection()方法,也比较简单。

  private final Collection<Object> object;
  @Override
  public boolean isCollection() {
    return true;
  }

  @Override
  public void add(Object element) {
    object.add(element);
  }

  @Override
  public <E> void addAll(List<E> element) {
    object.addAll(element);
  }

BaseWrapper

BaseWrapper抽象类实现了ObjectWrapper接口,实现了resolveCollection方法:功能是将指定的属性转为对象返回

protected Object resolveCollection(PropertyTokenizer prop, Object object) {
    if ("".equals(prop.getName())) {
      return object;
    } else {
      // 这里会循环调用,解析下层
      return metaObject.getValue(prop.getName());
    }
  }

同时还实现了getCollectionValue()和setCollectionValue()方法

这里用到MetaObject,MetaObject用来记录元数据

BeanWrapper

BeanWrapper继承BaseWrapper,实现了ObjectWrapper接口的get set方法,主要功能是获取相应的属性值和设置相应的属性值。

@Override
  public Object get(PropertyTokenizer prop) {
    if (prop.getIndex() != null) {
      // 不是单一属性,而是有数组
      Object collection = resolveCollection(prop, object);
      return getCollectionValue(prop, collection);
    } else {
      return getBeanProperty(prop, object);
    }
  }

  @Override
  public void set(PropertyTokenizer prop, Object value) {
    if (prop.getIndex() != null) {
      Object collection = resolveCollection(prop, object);
      setCollectionValue(prop, collection, value);
    } else {
      setBeanProperty(prop, object, value);
    }
  }

MapWrapper

MapWrapper也是继承BaseWrapper,和BeanWrapper的区别是用map来存储操作的

总结

这篇文章比较简单,主要讲解了一下获取类属性的类MetaClass,它的方法主要依赖于PropertyTokenizer类来进行解析,另外分析了一下封装对象元信息的接口ObjectWrapper,它的实现类有CollectionWrapper,BaseWrapper抽象类,BaseWrapper下的有BeanWrapper和MapWrapper等等子类,BeanWrapper实现get set方法来获取属性值或者设置属性值,而MapWrapper主要是用map结构来进行存储对象元信息。