分析mybatis 读取mybatis-config.xml文件的源码流程

代码见  GitHub:  https://github.com/tuyf/mybatisTest/tree/master/mybatisTest1

 

执行测试目录下的 UserTest 的 insertPerson方法, 进入MybatisUtil的静态方法块:

static{String resource="mybatis-config.xml";Reader reader =null;try {reader = Resources.getResourceAsReader(resource);} catch (IOException e) {e.printStackTrace();}sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
}

主要看 new SqlSessionFactoryBuilder().build(reader); 看mybatis是怎么样 根据reader配置文件信息 来创建sqlSessionFactory对象的。

 

方法 一层一层 进入:

 

 

所以 主要逻辑还是在 XMLConfigBuilder.parse() 中,

 

 

 

 

可以看到 类XMLConfigBuilder 的 parseConfiguration(XNode root)  方法中 对于 mybatis-config.xml配置文件中的各种节点 都有解析。

 

根节点是  <configuration>

</configuration>

 

项目 https://github.com/tuyf/mybatisTest/tree/master/mybatisTest1  的mybatis-config.xml配置文件上包含的节点有

properties
typeAliases
environments
mappers

 

以 typeHandlerElement(root.evalNode("typeHandlers")); 为例, typeHandler 是类型转换处理接口。

XMLConfigBuilder 的代码:
 private void typeHandlerElement(XNode parent) throws Exception {if (parent != null) {for (XNode child : parent.getChildren()) {if ("package".equals(child.getName())) {String typeHandlerPackage = child.getStringAttribute("name");typeHandlerRegistry.register(typeHandlerPackage);} else {String javaTypeName = child.getStringAttribute("javaType");String jdbcTypeName = child.getStringAttribute("jdbcType");String handlerTypeName = child.getStringAttribute("handler");Class<?> javaTypeClass = resolveClass(javaTypeName);JdbcType jdbcType = resolveJdbcType(jdbcTypeName);Class<?> typeHandlerClass = resolveClass(handlerTypeName);if (javaTypeClass != null) {if (jdbcType == null) {typeHandlerRegistry.register(javaTypeClass, typeHandlerClass);} else {typeHandlerRegistry.register(javaTypeClass, jdbcType, typeHandlerClass);}} else {typeHandlerRegistry.register(typeHandlerClass);}}}}}

 

 private void register(Type javaType, JdbcType jdbcType, TypeHandler<?> handler) {if (javaType != null) {Map<JdbcType, TypeHandler<?>> map = TYPE_HANDLER_MAP.get(javaType);if (map == null) {map = new HashMap<JdbcType, TypeHandler<?>>();TYPE_HANDLER_MAP.put(javaType, map);}map.put(jdbcType, handler);}ALL_TYPE_HANDLERS_MAP.put(handler.getClass(), handler);}
从XMLConfigBuilder的以上代码可以知道, 类型转换处理接口 最终 会把javaTypeClass的类,JdbcType的JdbcType对象 以及 这两个对象的映射typeHandlerClass类 注册到  typeHandlerRegistry 中,最终保存到TYPE_HANDLER_MAPALL_TYPE_HANDLERS_MAP 中 。

 

最后

XMLConfigBuilder 中的每种节点类型的读取和处理,如果是configuration里面的节点,都会set到

configuration的成员变量中。

 

在读取完 配置文件,并set到configuration中之后,

在SqlSessionFactoryBuilder中, 会有一个根据config配置信息,创建默认会话的方法:

return new DefaultSqlSessionFactory(config);