天天看點

MyBatis源碼分析:Configuration

MyBatis源碼分析:Configuration

mybatis的功能架構分為三層:

api接口層:提供給外部使用的接口api,開發人員通過這些本地api來操縱資料庫。接口層一接收到調用請求就會調用資料處理層來完成具體的資料處理。

資料處理層:負責具體的sql查找、sql解析、sql執行和執行結果映射處理等。它主要的目的是根據調用的請求完成一次資料庫操作。

基礎支撐層:負責最基礎的功能支撐,包括連接配接管理、事務管理、配置加載和緩存處理,這些都是共用的東西,将他們抽取出來作為最基礎的元件。為上層的資料處理層提供最基礎的支撐。

mybatis整個項目的包結構如下:

mybatis的最基礎和常用的是configuration類,它負責儲存mybatis的一些設定參數,它依賴或者相關的包有:

mapping:通過environment設定應用環境,environment依賴datasource和transaction包

transaction:事務

logging:設定日志

type:管理type注冊器,預設添加了很多常用類的注冊器

reflection:反射相關基礎類

cache:管理緩存

scripting:運作腳本

plugin:管理插件

execution:擷取execution

configuration類的所有屬性都是protected,其中一些屬性是final的,主要提供了兩個構造方法:

說明:

第一個構造方法是通過environment進行初始化,并調用第二個構造方法,environment封裝了資料源和事務,不同environment下使用的資料源和事務不一樣,例如,實際使用中會有生産和測試環境。

第二個構造方法,主要是注冊一些别名并設定預設的語言驅動。

configuration内部維護了以下幾種注冊器:

<code>mapperregistry</code>:管理mapper接口

<code>typehandlerregistry</code>:管理類型處理器

<code>typealiasregistry</code>:注冊别名,别名都是用的大寫

<code>languagedriverregistry</code>:管理語言驅動

這些注冊器内部都會維護一個或多個map,然後提供注冊<code>register</code>的方法,并且他們都是需要執行個體化才能使用的,而不是單例的。在一個mybatis應用的整個生命周期中,隻會存在一個configuration執行個體。

configuration内部有一些map類型的屬性:

可以看到,實際上是使用的<code>strictmap</code>。每一個<code>strictmap</code>都有一個名稱,<code>put</code>和<code>get</code>操作時需要判斷<code>key</code>是否為空,如果為空,則抛出異常。

configuration内部有一些collection類型的屬性:

為什麼接口使用的是collection而不是list?為什麼實作類使用的是linkedlist而不是arraylist?

configuration使用的一個例子:

總結:

configuration類儲存着mybatis的所有配置參數,并以此為入口為其他服務,如緩存、執行器等等,提供了一些接口,這樣友善集中管理和維護代碼,但似乎又違背了單一原則?所有配置參數都可以通過configuration來設定,意味着所有的配置都是可替代的,這樣就非常靈活了。