Mybatis对mapper的加载流程详解

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

加载方法mapperElement

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

mapperElement方法源码与详解如下图:


从源码可以得出一些结论:

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

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

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

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

解析包方法addMappers

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


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

介绍完关键类,再来看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程序员日常学习笔记,如理解有误欢迎各位交流讨论!


©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容