mybatis源碼解析 - 核心基礎組件之數據源組件

接上次分享了日誌組件後,咱們此次來分享一個比較重要mybatis基礎組件---數據源組件。提到數據源組件,我想問一個問題:請問從mybatis鏈接池獲取一個數據庫鏈接的過程是怎樣的?你知道嗎?這好像是BAT大廠的一道面試題吧。彆着急咱們慢慢來聊。java

總體設計架構面試

image.png

今天來分享一下數據源組件的源碼實現細節數據庫

工廠模式的設計思路設計模式

image.png

DataSourceFactory: 工廠模式的核心接口,調用者直接和工廠接口交互,用於獲取具體的工廠實現類;緩存

DataSource: java數據源的核心接口,用於抽象數據源行爲;安全

UnpooledDataSourceFactory: 非池化工廠的具體實現類,用於建立非池化的數據源對象;
數據結構

UnpooledDataSource:  主要用於構建原生的Connection對象;mybatis

PooledDataSourceFactory: 池化工廠的具體實現類,其繼承UnpooledDataSourceFactory非池化工廠類的行爲;主要職責建立池化的數據源對象;架構

PooledDataSource: 池化的數據源,它依賴UnpooledDataSource非池化數據源中鏈接等信息建立同步、線程安全的池化的數據源。ide

PooledConnection:  使用動態代理封裝和加強原生的Connection數據庫鏈接對象;

PoolState: 用於管理PooledConnection狀態的組件,經過維護兩個list分別管理空閒和活動的鏈接資源;

帶着以下問題解讀mybatis數據源組件設計實現源碼

  1. 數據源組件爲何採用工廠模式實現 ?

  2. 池化數據源和非池化數據源有什麼聯繫和區別,池化數據源須要考慮哪些問題?

數據源工廠源碼實現

image.png

非池化數據源源碼實現

image.png

池化數據源源碼實現

image.png

從組件以上的設計思路和源碼實現上,咱們不可貴出如下認知:

1. mybatis自身除了實現內置的數據源外,還要對三方數據源(如:durid, dbcp, c3p0等)的接入提供支持。這種業務設計需求下必須對數據源建立和管理,單獨提供入口,而且能方便的切換和適配。

2. 採用常規建立對象的方式, 包括:直接new具體數據源類建立對象和經過反射機制建立對象等方式,很明顯有如下缺陷:

缺陷一:對象的建立和使用的職責耦合在一塊兒, 違反了單一職責原則;

缺陷二:當業務擴展時,必需要修改代碼,違反了開閉原則;

那麼我認爲至少基於以上兩大原則,mybatis纔會考慮使用工廠模式。那工廠模式的明顯優勢有哪些呢?

1. 把對象的建立和使用的過程分開,這樣就達到了把二者的職責分離的目的;

2. 若是建立對象過程比較複雜,建立過程統一放到工廠維護,即減小了重複代碼,又方便了之後對相關過程代碼的修改;

3. 當業務擴展時,只須要增長工廠子類,符合開閉原則;

OK, 這個問題解決了。那接下來咱們將重點分析鏈接池化技術的設計實現源碼。

池化數據源構建

封裝池化、加強的數據庫鏈接

image.png

封裝對池化鏈接進行管理的核心數據結構

image.pngimage.png

idleConnections:空閒池化鏈接集合, 當鏈接使用完關閉時,會把它放進這個空閒鏈接集合緩存; 當獲取鏈接成功時,會將它從該集合中移除。

activeConnections:  正在使用的鏈接集合,當鏈接獲取成功時,會把池化鏈接對象放入此集合;當鏈接關閉時,會把它從該集合中移除。

這兩個list集合最終貫穿鏈接生命週期的始終。

池化數據源管理

拿鏈接的核心設計思路

image.png

拿鏈接方式和流程總結

image.png

上面正好也回答了文章一開始提出的問題!!

close鏈接的設計思路

image.png

關閉鏈接方式總結

image.png


總結

mybatis數據源組件其實設計很精妙,這種設計思路你們值得多思考和在咱們的項目中借鑑,尤爲是池化技術、設計模式!後面還爲分享mybatis一些優秀的組件和設計思想,請繼續關注!

相關文章
相關標籤/搜索