Mybatis对mapper的加载流程详解

今天来分析Configuration初始化的最后一部分mapper的加载。程序员

加载方法mapperElement

XMLConfigBuilder配置Configuration的parseConfiguration方法还剩最后一行解析代码:mapperElement(root.evalNode("mappers"));mybatis

mapperElement方法源码与详解以下图:app

 

从源码能够得出一些结论:学习

mappers节点支持mapper和package两种类型子节点;ui

package子节点只须要name一个属性;url

一个mapper子节点有且只能有url、resource、class三个属性中其中一个,不然会抛出异常;spa

mapperElement解析两种mappers子节点,主要代码我分红了4个部分,接下来逐一进行深刻解析。3d

 

解析包方法addMappers

首先来看解析包的方法使用的是configuration的addMappers方法,方法主要是涉及到一个MapperRegistry类型的属性mapperRegistry,addMappers主要流程以下图:代理

 

addMappers方法主要涉及到的是MapperRegistry这个类,这个类有两个属性:config、knownMappers。config指向的是configuration,knownMappers存放这class文件对应的MapperProxyFactoryMapperProxyFactory根据名字先猜想是建立mapper代理的工厂。xml

介绍完关键类,再来看addMappers主要分4步:

调用mapperRegistry属性的addMappers(String packageName)方法这个方法会调用另一个addMappers;

addMappers(String packageName, Class<?> superType)方法会遍历指定包下面全部属于superType子类的类,上一步传递的是Object.class,因此这里是遍历全部类,而后调用addMapper(mapperClass)方法;

addMapper(mapperClass)方法首先须要判断mapperClass必须是接口,再判断class是否已经存在,存在报异常。不存在则实例化一个MapperProxyFactory对象并put进knownMappers,最后根据class建立一个MapperAnnotationBuilder并调用parse方法。

最后是MapperAnnotationBuilder的parse方法,MapperAnnotationBuilder是解析mapper注解的,咱们后面详解。

 

加载package下的mapper总的流程看下来比较简单,实际上就是找到对应包下面全部的接口,而后根据接口建立一个MapperProxyFactory放到configuration属性mapperRegistry的knownMappers中

 

解析单个mapper

从解析单个mapper有三种状况,可是分两种状况,一种是有resource或者url属性的是直接根据属性值生成一个XMLMapperBuilder对象,而后执行parse方法,若是是由class属性值和加载包的最后一步方法类似,调用mapperRegistry的addMapper方法。

XMLMapperBuilder的初始化和parse简单介绍源码以下图:

 

解析mapper.xml的XMLMapperBuilder和最开始解析mybatis-config.xml的XMLConfigBuilder同样都是继承至mybatis的BaseBuilder,而且初始化流程也差很少。

能够看出XMLMapperBuilder类是解析mapper.xml最关键的类,这个类比较复杂,接下来的文章再来专门讲解它。

 

总结

mapper的注入支持两种方式,单个mapper注入或者整个包下面注入,也能够按加载class文件或者xml文件分红两种。单个mapper注入若是是根据url或者xml则是经过加载xml文件注入,经过url获取扫描整个包加载则是class方式进行注入。

经过xml加载是直接根据xml生成XMLMapperBuilder,而后执行parse方法。

经过class加载则是接口类生成MapperProxyFactory,放到MapperRegistry的map属性knownMappers中,最后经过MapperAnnotationBuilder执行parse进行解析,parse也会调用XMLMapperBuilder的parse方法。

后面的文章咱们先解读MapperAnnotationBuilder这个类,最终再来看最重要的类XMLMapperBuilder。

从目前源码能够得出一些须要注意的点:

一个mapper子节点有且只能有url、resource、class三个属性中其中一个,不然会抛出异常;

一个mapper只能被加载一次,重复加载会抛出异常。 

Java程序员平常学习笔记,如理解有误欢迎各位交流讨论!

相关文章
相关标签/搜索