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