天天看點

SpringBoot整合Mybatis-Plus源碼分析(六) 代理對象生成分析

作者:愛好程式設計的程式員老徐

上文說到Spring容器執行個體化MapperFactoryBean時候調setSqlSessionFactory時候會判斷成員屬性SqlSessionTemplate是否為空,如果為空則建立該對象,本文将要分析兩部分内容:

一、建立SqlSessionTemplate過程。

調用createSqlSessionTemplate方法,該方法截圖如下:

SpringBoot整合Mybatis-Plus源碼分析(六) 代理對象生成分析

createSqlSessionTemplate方法截圖

該方法手動建立一個SqlSessionTemplate對象,調用一個參數的構造方法,最後調用到三個參數的構造方法,該構造方法如下:

SpringBoot整合Mybatis-Plus源碼分析(六) 代理對象生成分析

SqlSessionTemplate的三個參數構造方法截圖

校驗SqlSessionFactory參數不能為空,ExecutorType參數不能為空,ExecutorType是MyBatis架構中的一個枚舉類型,用于指定執行SQL語句的執行器類型,預設是SIMPLE,表示每次執行都會建立一個新的預處理語句(PreparedStatement),不進行二級緩存和批量操作,适用于執行較簡單的SQL語句。指派變量this.sqlSessionProxy等于一個代理對象,可以看出sqlSessionProxy變量的類型是SqlSession,InvocationHandler的類型是SqlSessionInterceptor,由代理原理可以在調用sqlSessionProxy的方法時候首先會調用SqlSessionInterceptor的invoke方法,關于該處邏輯在真正執行sql語句的時候會詳細的分析,至此SqlSessionTemplate成員屬性建立完成。

二、MapperFactoryBean的getObject方法邏輯執行過程。

該對象實作了FactoryBean接口會調用該對象的getObject方法,該方法是一個懶加載方法,是在需要擷取該FactoryBean所建立的對象時才會觸發調用。這樣可以延遲對象的建立,實作懶加載的效果。該方法的截圖如下:

SpringBoot整合Mybatis-Plus源碼分析(六) 代理對象生成分析

getObject方法截圖如下

getSqlSession方法傳回一個第一步驟分析的對象SqlSessionTemplate,接着調用該對象的getMapper方法,該方法截圖如下:

SpringBoot整合Mybatis-Plus源碼分析(六) 代理對象生成分析

getMapper方法截圖

接着調用getConfiguration方法,從SqlSessionFacory對象中擷取MybatisConfiguration對象,接着調用該對象getMapper方法傳入dao層接口對象和本身對象,繼續調用到MybatisMapperRegistry對象的getMapper方法,該方法截圖如下:

SpringBoot整合Mybatis-Plus源碼分析(六) 代理對象生成分析

MybatisMapperRegistry的getMapper方法截圖

根據type類型從一個資料集合為Map<Class<?>, MybatisMapperProxyFactory<?>>的map對象中擷取MybatisMapperProxyFactory,此處不為空,因為在初始化SqlSessionFactory對象時候在addMapper中已經把該type類型接口和MybatisMapperProxyFactory映射起來了。

接着調用MybatisMapperProxyFactory的newInstance方法,該方法截圖如下:

SpringBoot整合Mybatis-Plus源碼分析(六) 代理對象生成分析

MybatisMapperProxyFactory的newInstance方法

該方法手動建立一個MybatisMapperProxy對象,該對象實作了InvocationHandler接口,同樣會執行它的invoke方法,接着調用newInstance方法傳入MybatisMapperProxy對象,newInstance最終建立一個代理對象傳回。

總結:

當需要Dao接口對象的代理時候會調用getObject方法,該方法首先調用SqlSessionTemplate的getMapper方法繼而調用MybatisConfiguration的getMapper方法然後調用MybatisMapperRegistrygetMapper方法擷取MybatisMapperProxyFactory,調用MybatisMapperProxyFactory的newInsance方法建立代理傳回。