Spring整合Mybatis原始碼解析

2021-10-01 23:19:00 字數 3607 閱讀 6736

mybatis-spring 的官網位址

具體可參考 官方文件() ,以及 上的demo**,不在這兒囉嗦。

首先,來看下sqlsessionfactorybean是如何構建sqlsessionfactory的,我們知道在spring中factorybean是一種特殊的bean,它的作用就是用來建立複雜的bean的,sqlsessionfactorybean#getobject方法就是用來建立sqlsessionfactory的:

public sqlsessionfactory getobject() throws exception 

//返回內部屬性sqlsessionfactory

return this.sqlsessionfactory;

}

最終的邏輯在sqlsessionfactorybean#sqlsessionfactorybean方法中:

protected sqlsessionfactory buildsqlsessionfactory() throws exception  

//或者配置了mybaits主配置檔案位址,則使用xmlconfigbuilder來解析(和原生的**一樣),注意這兒只是new了xmlconfigbuilder,並沒有parse。

else if (this.configlocation != null)

//前兩者都沒有,則用預設的配置,即new configuration()。

else

...//如果在sqlsessionfactorybean中配置別名包路徑,則掃瞄包下的類,並註冊滿足條件的類的別名。

//注意,這兒的掃瞄實現就使用了spring的掃瞄方式,即使用resource體系。

if (haslength(this.typealiasespackage))

//如果在sqlsessionfactorybean中配置了別名,則直接註冊。

if (!isempty(this.typealiases)) );

} //如果在sqlsessionfactorybean中配置了外掛程式,則註冊外掛程式

if (!isempty(this.plugins)) );

} //如果在sqlsessionfactorybean中配置了型別處理器包掃瞄路徑,則包下的類,並註冊滿足條件的型別處理器。

if (haslength(this.typehandlerspackage))

//如果在sqlsessionfactorybean中配置了型別處理器,則直接註冊型別處理器

if (!isempty(this.typehandlers)) );

} ...

//這兒進行xmlconfigbuilder解析

if (xmlconfigbuilder != null)

//注意,前面的configuration中,就算已經有了解析了環境物件,不會使用。這兒會全新new乙個environment出來,器事務工廠為springmanagedtransactionfactory。

targetconfiguration.setenvironment(new environment(this.environment,

this.transactionfactory == null ? new springmanagedtransactionfactory() : this.transactionfactory,

this.datasource));

......

...}

}//由sqlsessionfactorybuilder#build方法,傳入configuration物件,構建乙個defaultsqlsessionfactory出來,這和原生的一樣。

return this.sqlsessionfactorybuilder.build(targetconfiguration);

}

可以看出,使用sqlsessionfactorybean來構建sqlsessionfactory,和原生的方式區別不大,支援mybatis的主配置檔案方式,也可將很多配置直接放到sqlsessionfactorybean中來,從而省略mybatis的主配置檔案。這裡面最大的不同點就是環境中,事務工廠的實現類為springmanagedtransactionfactory。

}

public listselectlist(string statement, object parameter)
所有的sqlsession呼叫,都委託給了sqlsessionproxy,而sqlsessionproxy是在sqlsessiontemplate初始化時建立出來的:

public sqlsessiontemplate(sqlsessionfactory sqlsessionfactory, executortype executortype,

persistenceexceptiontranslator exceptiontranslator) , new sqlsessioninterceptor());

}

這個sqlsessioninterceptor就是sqlsessiontemplate的核心所在了,為什麼sqlsessiontemplate是執行緒安全的,就是它的功勞:

//sqlsessioninterceptor實現了invocationhandler介面

private class sqlsessioninterceptor implements invocationhandler

return result;

...} finally }}}

跟到sqlsessionutils#getsqlsession方法中:

public static sqlsession getsqlsession(sqlsessionfactory sessionfactory, executortype executortype,

persistenceexceptiontranslator exceptiontranslator)

//否則呼叫sessionfactory#opensession方法,開啟乙個新的sqlsession,這就回到了mybaits的**。

logger.debug(() -> "creating a new sqlsession");

session = sessionfactory.opensession(executortype);

//將新建立的sqlsession註冊繫結到事務同步管理器中,以便於同乙個事務中,可以復用sqlsession。

registersessionholder(sessionfactory, executortype, exceptiontranslator, session);

return session;

}

現在就可以解釋為什麼sqlsessiontemplate是執行緒安全的,那是因為如果不是同一執行緒,那麼每次getsqlsession都會獲取乙個新的sqlsession用於真正的執行,因此完全不會有任何執行緒問題。

最後來來個示意圖幫助理解:

通過Spring整合MyBatis

step1.導包 step2.新增spring配置檔案 bean來代替 sqlsessionfactorybean step3.配置sqlsessionfactorybean step4.實體類step5.對映檔案spring容器裡面 預設的id是首字母小寫之後的介面名 step8.啟動spring...

spring整合MyBatis總結

service層的物件建立的底層實現,是依賴spring ioc 的bean id來建立,不管是顯示bean,還是自動裝配。再底層細緻,就是反射 無參構造方法 層與層之間都必須有需要有spring bean 的定義 不管是顯示定義,還是隱藏定義 類與類之間的依賴 原始是通過在配置檔案裡寫明ref實現...

Spring整合MyBatis 基礎

基礎準備工作 整合準備工作 spring配置檔案,加上context命名空間,用於載入properties檔案 開啟載入properties檔案 配置資料來源druid 備用 定義service層bean,注入dao層bean dao的bean無需定義,使用 自動生成 整合工作 匯入spring整合...