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