聊聊Mybatis的反射之ObjectWrapper

举报
周杰伦本人 发表于 2022/07/28 19:18:39 2022/07/28
1.2k+ 0 0
【摘要】 聊聊Mybatis的反射之ObjectWrapper MetaClass ObjectWrapper CollectionWrapper BaseWrapper BeanWrapper MapWrapper 总结 聊聊Mybatis的反射之ObjectWrapper这篇文章我们将讲授Mybatis反射的对象包装的类 MetaClassMetaClass主要是用于获取类的属性,它的构造方法中...

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

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

作者其他文章

评论(0

抱歉,系统识别当前为高风险访问,暂不支持该操作

    全部回复

    上滑加载中

    设置昵称

    在此一键设置昵称,即可参与社区互动!

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。