1、作用
可以在sql執行前后 結果映射 參數解析階段做攔截處理(AOP)
如:日志打印 性能監控等
2、攔截的4個對象
Execute StatementHandle ParameterHandle ResultHandle
- Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed),主要用於sql重寫。
- ParameterHandler (getParameterObject, setParameters),用於參數處理。
- ResultSetHandler (handleResultSets, handleOutputParameters),用於結果集二次處理。
- StatementHandler (prepare, parameterize, batch, update, query),用於jdbc層的控制。

3、使用
定義哪個對象 哪個方法進行攔截
如:plugin方法返回代理對象

4、原理
具體的方法定義可以參見每個類方法的簽名,這里就不詳細展開了。這四個類被創建后不是直接返回,而是創執行了interceptorChain.pluginAll(parameterHandler)才返回。如下所示:
pluginAll最終調用每個攔截器的plugin方法,返回代理對象,如果有多個攔截器,就會一層層代理。
//Configuration 中
public ParameterHandler newParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql) {
ParameterHandler parameterHandler = mappedStatement.getLang().createParameterHandler(mappedStatement, parameterObject, boundSql);
parameterHandler = (ParameterHandler) interceptorChain.pluginAll(parameterHandler);
return parameterHandler;
}
public ResultSetHandler newResultSetHandler(Executor executor, MappedStatement mappedStatement, RowBounds rowBounds, ParameterHandler parameterHandler,
ResultHandler resultHandler, BoundSql boundSql) {
ResultSetHandler resultSetHandler = new DefaultResultSetHandler(executor, mappedStatement, parameterHandler, resultHandler, boundSql, rowBounds);
resultSetHandler = (ResultSetHandler) interceptorChain.pluginAll(resultSetHandler);
return resultSetHandler;
}
public StatementHandler newStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
StatementHandler statementHandler = new RoutingStatementHandler(executor, mappedStatement, parameterObject, rowBounds, resultHandler, boundSql);
statementHandler = (StatementHandler) interceptorChain.pluginAll(statementHandler);
return statementHandler;
}
public Executor newExecutor(Transaction transaction) {
return newExecutor(transaction, defaultExecutorType);
}
// Execute默認使用SimpleExecutor
public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
executorType = executorType == null ? defaultExecutorType : executorType;
executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
Executor executor;
if (ExecutorType.BATCH == executorType) {
executor = new BatchExecutor(this, transaction);
} else if (ExecutorType.REUSE == executorType) {
executor = new ReuseExecutor(this, transaction);
} else {
executor = new SimpleExecutor(this, transaction);
}
if (cacheEnabled) {
executor = new CachingExecutor(executor);
}
executor = (Executor) interceptorChain.pluginAll(executor);
return executor;
}
5、總結
使用的設計模式:代理模式、責任鏈模式
參考:
https://www.cnblogs.com/chenpi/p/10498921.htm
https://www.cnblogs.com/zhjh256/p/11516878.html
https://my.oschina.net/u/4365042/blog/3344199l

