http://www.mybatis.org/mybatis-3/zh/configuration.html#mappers
1)判断
最后就是<mappers>标签的解析。
扫描类型 | 含义 |
resource | 相对路径 |
url | 绝对路径 |
package | 包 |
package 包 | 单个接口 |
首先会判断是不是接口,只有接口才解析;然后判断是不是已经注册了,单个Mapper重复注册会抛出异常。
2)注册
XMLMapperBuilder.parse()方法,是对Mapper 映射器的解析。里面有两个方法:configurationElement()—— 解析所有的子标签, 其中buildStatementFromContext()最终获得MappedStatement 对象。
bindMapperForNamespace()——把namespace(接口类型)和工厂类绑定起来。
无论是按package 扫描,还是按接口扫描,最后都会调用到MapperRegistry 的addMapper()方法。
MapperRegistry 里面维护的其实是一个Map 容器,存储接口和代理工厂的映射关系。
问题:为什么要放一个代理工厂呢?代理工厂用来干什么?
3)处理注解
除了映射器文件,在这里也会去解析Mapper 接口方法上的注解。在addMapper()方法里面创建了一个MapperAnnotationBuilder,我们点进去看一下parse()方法。
parseCache() 和parseCacheRef() 方法其实是对@CacheNamespace 和@CacheNamespaceRef 这两个注解的处理。
parseStatement()方法里面的各种getAnnotation(),都是对注解的解析,比如@Options,@SelectKey,@ResultMap 等等。
最后同样会解析成MappedStatement 对象,也就是说在XML 中配置,和使用注解配置,最后起到一样的效果。
4)收尾
如果注册没有完成,还要从Map 里面remove 掉。
// MapperRegistry.java
finally {
if (!loadCompleted) {
knownMappers.remove(type);
}
}
最后,MapperRegistry 也会放到Configuration 里面去。
第二步是调用另一个build()方法,返回DefaultSqlSessionFactory。
总结
在这一步,我们主要完成了config 配置文件、Mapper 文件、Mapper 接口上的注解的解析。
我们得到了一个最重要的对象Configuration,这里面存放了全部的配置信息,它在属性里面还有各种各样的容器。
最后,返回了一个DefaultSqlSessionFactory,里面持有了Configuration 的实例。