解析Settings节点
<settings>
<setting name="cacheEnabled" value="true"/>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="autoMappingBehavior" value="PARTIAL"/>
</settings>
settings节点中的内容较多,用于一些全局性的配置。mybatis会解析这个标签,并将最终信息存储到configuration对象中。
为了保证子节点属性的正确性,因为这些子节点的属性值,最终都会通过对应的setter方法设置到configuration对象中,因此只需获取到configuration中的所有的getter/setter方法即可。
为了获取类的这些元信息,引入MetaClass类:
public class MetaClass {
// 解析器工厂
private final ReflectorFactory reflectorFactory;
// 解析器
private final Reflector reflector
}
其中reflectorFactory内部通过一个map缓存class–Reflector,用的时候直接从缓存中获取即可。
Reflector 缓存类的元信息,在构造方法中完成类的解析工作,并将类的元信息缓存到集合中。
这样可以通过一个类的class对象之间获取到该类对应的Reflector,进而获取到对应的元信息。
反射操作速度较慢,消耗性能,缓存结果,空间换时间。
private Properties settingsAsProperties(XNode context) {
// context --- <settings><settings/>
if (context == null) {
return new Properties();
}
Properties props = context.getChildrenAsProperties();
// Check that all settings are known to the configuration class
// 获取configuration的原信息
MetaClass metaConfig = MetaClass.forClass(Configuration.class, localReflectorFactory);
for (Object key : props.keySet()) {
// 检查有没有写错
if (!metaConfig.hasSetter(String.valueOf(key))) {
throw new BuilderException("The setting " + key + " is not known. Make sure you spelled it correctly (case sensitive).");
}
}
return props;
}
最终setter到Configuration对象中。