Mybatis是一个ORM(Object Relation Mapping)框架,既然是ORM框架,那么DB与POJO之间的相互映射必然是其重要工作之一。Reflector是对反射的二次封装。它更侧重于增强getter/setter方法。Reflector对Getter/Setter的增强主要围绕以下几点:
1.缓存Class信息,提高效率。
缓存class信息实际上并不是由Reflector本身来完成的,而是由ReflectorFactory接口负责,其接口定义如下:
/**
* 缓存Reflector对象,以达到复用的目的
* */
public interface ReflectorFactory {
/**
* 缓存开关
* */
boolean isClassCacheEnabled();
void setClassCacheEnabled(boolean classCacheEnabled);
/**
* 查找并返回Reflector
* */
Reflector findForClass(Class<?> type);
}
mybatis提供了默认实现:
public class DefaultReflectorFactory implements ReflectorFactory {
private boolean classCacheEnabled = true;
/**
* 缓存Reflector
* **/
private final ConcurrentMap<Class<?>, Reflector> reflectorMap = new ConcurrentHashMap<>();
public DefaultReflectorFactory() {
}
@Override
public boolean isClassCacheEnabled() {
return classCacheEnabled;
}
@Override
public void setClassCacheEnabled(boolean classCacheEnabled) {
this.classCacheEnabled = classCacheEnabled;
}
@Override
/**
* 查找并返回Reflector对象,如果开启Reflector缓存,则从缓存中读取,
* 否则new一个返回
* 如果从缓存中查找但没有找到,new一个存入缓存后返回。
* **/
public Reflector findForClass(Class<?> type) {
// 如果启用classCacheEnable 则从reflectorMap中查找,如果存在则返回,如果不存在,new一个存入reflectorMap中并返回
if (classCacheEnabled) {
// synchronized (type) removed see issue #461
return MapUtil.computeIfAbsent(reflectorMap, type, Reflector::new);
} else {
//否则直接new后返回
return new Reflector(type);
}
}
}
2.使用Invoker接口统一操作Property/Field
有一些Bean中没有提供getter/setter,在这种情况下,mybaits会调用 field.get(),field.set()来完成读写操作,而提供了getter/setter的则调用getter/setter方法来完成读写,为了屏蔽这种差异,mybatis抽象出了Invoker接口。
3.解决冲突