ibatis_2.3源码水平浅析(待续)

题记:

    总得开个头吧。前一篇垂直分析。

客户端初始化

Reader reader=null;
SqlMapClient sqlMap=null; 
Reader =com.ibatis.common.resources.Resources.getResourceAsReader (filename);
sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);
reader.close();

    com.ibatis.common.resources.Resources.getResourceAsReader (filename);的方法是从当前ClassLoader里或SystemLoader里去加载名为filename的文件,并创建InputStreamReader返回。这里提下ClassLoader,JVM有Bootstrap,Ext,App的ClassLoader,用户类一般用AppClassLoader,会用Thread.getContextClassLoader()取到。关键代码如下:

private static ClassLoader getClassLoader() {// 取ContextClassLoader
    return Thread.currentThread().getContextClassLoader();
  }
 public static InputStream getResourceAsStream(ClassLoader loader, String resource) throws IOException {
    InputStream in = null;
    if (loader != null) in = loader.getResourceAsStream(resource);
    if (in == null) in = ClassLoader.getSystemResourceAsStream(resource);
    if (in == null) throw new IOException("Could not find resource " + resource);
    return in;
  }

    构建SqlMapConfigParser来做初始化工作,初始化Variables,NodeletParser(The NodeletParser is a callback based parser similar to SAX),新建SqlMapExecutorDelegate(主要执行类),SqlMapClientImpl(delegate代理类,并处理线程安全)。关键代码如下:

public SqlMapConfigParser() {
    this(null, null);
  }
  public SqlMapConfigParser(XmlConverter sqlMapConfigConv, XmlConverter sqlMapConv) {
    super(new Variables());
    parser.setValidation(true);
  parser.setEntityResolver(new SqlMapClasspathEntityResolver());// 把有关DTD的东西放到一个private static HashMap里叫doctypeMap。

    vars.sqlMapConfigConv = sqlMapConfigConv;
    vars.sqlMapConv = sqlMapConv;
    vars.delegate = new SqlMapExecutorDelegate();
    vars.typeHandlerFactory = vars.delegate.getTypeHandlerFactory();
    vars.client = new SqlMapClientImpl(vars.delegate);
    registerDefaultTypeAliases(); // 调用typeHandlerFactory,关联关键类类型

    addSqlMapConfigNodelets();
    addGlobalPropNodelets();
    addSettingsNodelets();
    addTypeAliasNodelets();
    addTypeHandlerNodelets();
    addTransactionManagerNodelets();
    addSqlMapNodelets();
    addResultObjectFactoryNodelets();
  }

    在这里SqlMapExecutorDelegate()初始化是重点,他需要初始化XML-CONFIG中所有的关键数据,并且存储和处理由NodeletParser来做。

XML配置文件解析思路

    ibatis解析XML是的DOM模型,NodeletParser实现了一个类似以"/Father/Child"字符串为key,匿名new Nodelet()类为value(匿名Nodelet类定义好自己的 public void process(Node node)方法)的回调函数 。当在解析XML的时候,根据当前解析到的某个node,并取得node的getNodeName,getAttributes,getChildNodes为key,来调用相应的回调函数。父子关系则为/Father/Child这种来标识,attribute则为:/Father/@attri1@attri2。

这种处理XML的方式对我来说还是挺陌生的,正好自己的“小爬虫”里运用运用。而且假如需要更改XML中某个NodeName的时候,只需要更改Map的相应Key的值,而不用更改处理逻辑,让人感觉很简约。

相关推荐