1Mybatis插件介紹
Mybati s作為?個(gè)應(yīng)??泛的優(yōu)秀的ORM開源框架,這個(gè)框架具有強(qiáng)?的靈活性,在四?組件(Executor、StatementHandler、ParameterHandler、ResultSetHandler)處提供了簡單易?的插 件擴(kuò)展機(jī)制。Mybatis對持久層的操作就是借助于四?核?對象。MyBatis?持?插件對四?核?對象進(jìn) ?攔截,對mybatis來說插件就是攔截器,?來增強(qiáng)核?對象的功能,增強(qiáng)功能本質(zhì)上是借助于底層的 動(dòng)態(tài)代理實(shí)現(xiàn)的,換句話說,MyBatis中的四?對象都是代理對象

2 Mybatis插件原理
MyBatis所允許攔截的?法如下:
執(zhí)?器Executor (update、query、commit、rollback等?法);
SQL語法構(gòu)建器StatementHandler (prepare、parameterize、batch、updates query等? 法);
參數(shù)處理器ParameterHandler (getParameterObject、setParameters?法);
結(jié)果集處理器ResultSetHandler (handleResultSets、handleOutputParameters等?法);
Mybatis插件原理
在四?對象創(chuàng)建的時(shí)候
1、每個(gè)創(chuàng)建出來的對象不是直接返回的,?是interceptorChain.pluginAll(parameterHandler);
2、獲取到所有的Interceptor (攔截器)(插件需要實(shí)現(xiàn)的接?);調(diào)? interceptor.plugin(target);返 回 target 包裝后的對象
3、插件機(jī)制,我們可以使?插件為?標(biāo)對象創(chuàng)建?個(gè)代理對象;AOP (?向切?)我們的插件可 以
為四?對象創(chuàng)建出代理對象,代理對象就可以攔截到四?對象的每?個(gè)執(zhí)?;
攔截
插件具體是如何攔截并附加額外的功能的呢?以ParameterHandler來說
public ParameterHandler newParameterHandler(MappedStatement mappedStatement,
Object object, BoundSql sql, InterceptorChain interceptorChain) {
ParameterHandler parameterHandler =
mappedStatement.getLang().createParameterHandler(mappedStatement, object, sql);
parameterHandler = (ParameterHandler)
interceptorChain.pluginAll(parameterHandler);
return parameterHandler;
}
public Object pluginAll(Object target) {
for (Interceptor interceptor : interceptors) {
target = interceptor.plugin(target);
}
return target;
}
interceptorChain保存了所有的攔截器(interceptors),是mybatis初始化的時(shí)候創(chuàng)建的。調(diào)?攔截器鏈中的攔截器依次的對?標(biāo)進(jìn)?攔截或增強(qiáng)。interceptor.plugin(target)中的target就可以理解為mybatis中的四?對象。返回的target是被重重代理后的對象.
如果我們想要攔截Executor的query?法,那么可以這樣定義插件:
@Intercepts({
@Signature(
type = Executor.class,
method = "query",
args= {MappedStatement.class,Object.class,RowBounds.class,ResultHandler.class} )
})
public class ExeunplePlugin implements Interceptor {
//省略邏輯
}
這樣MyBatis在啟動(dòng)時(shí)可以加載插件,并保存插件實(shí)例到相關(guān)對象(InterceptorChain,攔截器鏈) 中。待準(zhǔn)備?作做完后,MyBatis處于就緒狀態(tài)。我們在執(zhí)?SQL時(shí),需要先通過DefaultSqlSessionFactory創(chuàng)建 SqlSession。Executor 實(shí)例會(huì)在創(chuàng)建 SqlSession 的過程中被創(chuàng)建, Executor實(shí)例創(chuàng)建完畢后,MyBatis會(huì)通過JDK動(dòng)態(tài)代理為實(shí)例?成代理類。這樣,插件邏輯即可在 Executor相關(guān)?法被調(diào)?前執(zhí)?。