下面,开始解析plugins的XML
pluginElement(root.evalNode("plugins"))
debug的代码位于
stop in org.apache.ibatis.builder.xml.XMLConfigBuilder.pluginElement
首先关于寻址类的优先级,是可以通过别名来查找的
@SuppressWarnings("unchecked")
// throws class cast exception as well if types cannot be assigned
public <T> Class<T> resolveAlias(String string) {
// 看到这里了
try {
if (string == null) {
return null;
}
// issue #748
//
String key = string.toLowerCase(Locale.ENGLISH);
Class<T> value;
//可以是通过别名寻址
if (TYPE_ALIASES.containsKey(key)) {
value = (Class<T>) TYPE_ALIASES.get(key);
} else {
//否则正常初始化类
value = (Class<T>) Resources.classForName(string);
}
//返回结果
return value;
//结束
} catch (ClassNotFoundException e) {
throw new TypeException("Could not resolve type alias '" + string + "'. Cause: " + e, e);
}
}
别名你懂的,如果没有别名,就认为你指定的是一个类,正常初始化这个类
---
private void pluginElement(XNode parent) throws Exception {
// 如果定义了plugin节点
if (parent != null) {
//遍历每1个子节点
for (XNode child : parent.getChildren()) {
//获取interceptor的值
String interceptor = child.getStringAttribute("interceptor");
//其它子节点作为属性存在
Properties properties = child.getChildrenAsProperties();
//指定的interceptor实例化,所以传递的这个类必须实现Interceptor接口
Interceptor interceptorInstance = (Interceptor) resolveClass(interceptor).newInstance();
//属性设置,自己实现
interceptorInstance.setProperties(properties);
//非常重要
configuration.addInterceptor(interceptorInstance);
//看到这里了
}
}
}
public class InterceptorChain {
private final List<Interceptor> interceptors = new ArrayList<Interceptor>();
public Object pluginAll(Object target) {
for (Interceptor interceptor : interceptors) {
target = interceptor.plugin(target);
}
return target;
}
public void addInterceptor(Interceptor interceptor) {
// 有序依次添加
interceptors.add(interceptor);
}
很简单,没啥好说的。