写点什么

聊聊 Mybatis 的反射之 ObjectWrapper

作者:周杰伦本人
  • 2022-11-22
    山东
  • 本文字数:1806 字

    阅读完需:约 6 分钟

聊聊 Mybatis 的反射之 ObjectWrapper

这篇文章我们将讲授 Mybatis 反射的对象包装的类

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 来进行解析。对于 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); }
复制代码


通过源码我们知道,它的方法主要依赖成员变量 Collection 集合来实现的。

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 结构来进行存储对象元信息。

发布于: 刚刚阅读数: 3
用户头像

还未添加个人签名 2020-02-29 加入

公众号《周结论本人》,多平台优质博主

评论

发布
暂无评论
聊聊Mybatis的反射之ObjectWrapper_11月月更_周杰伦本人_InfoQ写作社区