1. 程式人生 > >Mybatis攔截器(插件實現原理)

Mybatis攔截器(插件實現原理)

通過 source hand page fault PE ace sign targe

在mybatis的mybatis.cfg.xml中插入:
    <plugins>
        <plugin interceptor="cn.sxt.util.PageInterceptor"/>
    </plugins>
    <mappers>
        <mapper resource="cn/sxt/vo/user.mapper.xml"/>
    </mappers>
對於Executor,Mybatis中有幾種實現:BatchExecutor、ReuseExecutor、SimpleExecutor和CachingExecutor。 這個時候如果你覺得這幾種實現對於Executor接口的query方法都不能滿足你的要求,那怎麽辦呢?是要去改源碼嗎?當然不。 我們可以建立一個Mybatis攔截器用於攔截Executor接口的query方法,在攔截之後實現自己的query方法邏輯, 之後可以選擇是否繼續執行原來的query方法。
public interface Interceptor {
  Object intercept(Invocation invocation) throws Throwable;
  Object plugin(Object target);
  void setProperties(Properties properties)
}
plugin方法是攔截器用於封裝目標對象的,通過該方法我們可以返回目標對象本身,也可以返回一個它的代理。 setProperties方法是用於在Mybatis配置文件中指定一些屬性的。 @Intercepts用於表明當前的對象是一個Interceptor, @Signature則表明要攔截的接口、方法以及對應的參數類型。
@Intercepts( {
       @Signature(method = "query", type = Executor.class, args = {
              MappedStatement.class, Object.class, RowBounds.class,
              ResultHandler.class }),
       @Signature(method = "prepare", type = StatementHandler.class, args = { Connection.class }) })
?
@Intercepts標記了這是一個Interceptor,然後在@Intercepts中定義了兩個@Signature,即兩個攔截點。 @Signature我們定義了該Interceptor將攔截Executor接口中參數類型為MappedStatement、Object、RowBounds和ResultHandler的query方法; 第二個@Signature我們定義了該Interceptor將攔截StatementHandler中參數類型為Connection的prepare方法。 只能攔截四種類型的接口:Executor、StatementHandler、ParameterHandler和ResultSetHandler。(動態代理模式) 攔截器實現Mybatis分頁的一個思路就是攔截StatementHandler接口的prepare方法,

Mybatis攔截器(插件實現原理)