上一篇文章分析了mapper註解關鍵類MapperAnnotationBuilder,今天來看mapper的項目瞭解析關鍵類XMLMapperBuilder。程序員
基礎介紹
回顧下以前是在分析configuration的初始化過程,已經進行到了最後一步mapperElement(root.evalNode("mappers")),這個方法裏有兩種解析mapper的方法,一種是解析類,一種是解析xml文件,上一篇文章在講解析類中的註解,今天說到的就是解析xml的流程,關鍵代碼以下:sql
解析mapper有4種狀況能夠分紅根據類解析和根據xml文件解析兩類,此次是後面這類,主體方法仍是比較簡單。mybatis
首先根據inputStream, configuration, resource或url, configuration.getSqlFragments()四個參數初始化一個XMLMapperBuilder;app
而後執行XMLMapperBuilder對象的parse方法;工具
初始化XMLMapperBuilder
初始化過程源碼已在上圖的右側部分,初始化XMLMapperBuilder方法的流程與加載mybatis的配置文件關鍵類XMLConfigBuilder及其類似,都是經過xml文件建立XPathParser對象做爲XMLMapperBuilder對象的parse屬性。最後執行parse方法去解析xml文件內容。學習
實際上XMLMapperBuilder與XMLConfigBuilder都繼承BaseBuilder類,經過名字也能夠看出來他們採用的是構建者模式,在結合他們的使用流程就可以更加理解mybatis採用構建者模式對不一樣的xml解析過程。ui
在初始化方法中又出現了一個關鍵類MapperBuilderAssistant,這個在上一篇分析MapperAnnotationBuilder類是發現MapperAnnotationBuilder解析了全部的註解而後把解析的內容給到MapperBuilderAssistant對象,而後經過MapperBuilderAssistant對象生成的對象具體sql的MappedStatement對象。url
這裏能夠大膽猜想XMLMapperBuilder應該也是同樣,解析出xml中全部信息而後給到MapperBuilderAssistant去生產MappedStatement對象。spa
XMLMapperBuilder和MapperAnnotationBuilder都是工具人,MapperBuilderAssistant纔是真正生成MappedStatement對象的類。xml
parse方法
parse方法比較簡單在上圖中也已經把源碼貼出來了,主要分四步:驗證重複加載、加載mapper節點並解析、綁定名稱空間、解決未處理的方法。
第一三步比較簡單就不在詳細說了,而第四步是也就是parse方法最後三行代碼,他的主要做用是解決在第二步解析mapper時不能處理的一些數據進行處理,代碼比較簡單不在詳細分析了,源碼以下:
configurationElement方法
能夠看出來最最關鍵的方法仍是parse方法的configurationElement方法,他纔是真正解析mapper.xml的方法,方法源碼以下圖:
方法比較簡單,就是讀取對應節點的數據,進行解析,重點是調用的這些解析方法,能夠看到一些咱們平時最多見的好比mapper節點上的namespace屬性,還有常見的resultMap節點、sql節點等。
這裏我簡單點就只看最後一行解析具體的select|insert|update|delete節點的方法,由於他們對應的就是咱們具體的sql了。根據上圖能夠看到獲取全部的這類節點,而後遍歷生成了一個XMLStatementBuilder的對象並執行parseStatementNode方法。接下來來看XMLStatementBuilder類。
XMLStatementBuilder類
XMLStatementBuilder的源碼以下圖:
XMLStatementBuilder與XMLMapperBuilder同樣都是繼承BaseBuilder類,它的XNode類型屬性context對應mapper文件中一個select、update等節點。初始化方法沒什麼說的,主要看parseStatementNode方法,上圖中已經截圖一部分,剩下部分以下圖:
parseStatementNode方法並不複雜,都是在讀取context的數據,主要是最後圈出來的代碼,和上一篇解析MapperAnnotationBuilder類最後調用的是同一方法。
前面猜錯了啊,XMLMapperBuilder連工具人都算不上,XMLStatementBuilder纔算生成MappedStatement的工具人。不過仔細一想也是對的,XMLMapperBuilder對應的是一個mapper.xml文件,而要生成的MappedStatement對應的是具體的一條CRUD語句,一個xml是包含多條CRUD語句的。
總結
一個XMLMapperBuilder對應一個mapper.xml文件,而XMLMapperBuilder可以從xml文件中獲取多個CRUD語句對應的節點,每一個節點對應生成一個XMLStatementBuilder對象,XMLStatementBuilder解析節點中全部信息後與MapperAnnotationBuilder解析出註解中包含的信息同樣交給MapperBuilderAssistant去生成一個MappedStatement。
Java程序員平常學習筆記,如理解有誤歡迎各位交流討論!