Mybatis攔截器的使用分為兩步,自定義攔截器類、注冊攔截器類
一、自定義攔截器類
自定義的攔截器需要實現Interceptor接口,並且在自定義攔截器類上添加@Intercepts注解。
1. Interceptor接口
Interceptor接口中聲明三個方法(此接口系統自己已經寫好了,我們不必再重新聲明接口):
public interface Interceptor { Object intercept(Invocation var1) throws Throwable; Object plugin(Object var1); void setProperties(Properties var1); }
Object intercept(Invocation var1) throws Throwable;
此方法實現代理攔截對象執行的方法,代碼體是我們要自定義實現的代碼邏輯。
Object plugin(Object var1);
plugin方法是攔截器用於封裝目標對象的,通過該方法我們可以返回目標對象本身,也可以返回一個它的代理。當返回的是代理的時候我們可以對其中的方法進行攔截來調用intercept方法 -- Plugin.wrap(target, this);當返回的是當前對象的時候 就不會調用intercept方法,相當於當前攔截器無效。
void setProperties(Properties properties);
用於在Mybatis配置文件中指定一些屬性的,注冊當前攔截器的時候可以設置一些屬性。
2. @Intercepts注解
Intercepts注解需要一個Signature(攔截點)參數數組。通過Signature來指定攔截哪個對象里面的哪個方法。@Intercepts注解定義如下(此注解系統以默認實現如代碼):
@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface Intercepts { /** * 定義攔截點 * 只有符合攔截點的條件才會進入到攔截器 */ Signature[] value(); }
Signature來指定咱們需要攔截那個類對象的哪個方法。定義如下:
@Documented @Retention(RetentionPolicy.RUNTIME) @Target({}) public @interface Signature { /** * 定義攔截的類 Executor、ParameterHandler、StatementHandler、ResultSetHandler當中的一個 */ Class<?> type(); /** * 在定義攔截類的基礎之上,在定義攔截的方法 */ String method(); /** * 在定義攔截方法的基礎之上在定義攔截的方法對應的參數, * JAVA里面方法可能重載,不指定參數,不曉得是那個方法 */ Class<?>[] args(); }
舉一個例子來說明,比如我們自定義一個MybatisInterceptor類,來攔截Executor類里面的兩個query。自定義攔截類MybatisInterceptor:
@Intercepts({ @Signature( type = Executor.class , method = "update" , args = {MappedStatement.class, Object.class} ), @Signature( type = Executor.class , method = "query" , args ={MappedStatement.class , Object.class , RowBounds.class , ResultSetHandler.class} ) }) public class MybatisInterceptor implements Interceptor { /* * mybatis運行時要執行的攔截方法 * */ @Override public Object intercept(Invocation invocation ) throws Throwable{ if(invocation.getTarget()instanceof RoutingStatementHandler){ //to do 自己的邏輯 } return invocation.proceed(); } /* * target:攔截對象 * * */ @Override public Object plugin(Object target){ // 當目標類是StatementHandler類型時,才包裝目標類,否者直接返回目標本身,減少目標被代理的次數 return (target instanceof RoutingStatementHandler)? Plugin.wrap(target,this):target; } //實現插件參數傳遞 @Override public void setProperties(Properties properties){ } }
二、注冊攔截器類
注冊攔截器就是去告訴Mybatis去使用我們的攔截器。注冊攔截器類非常的簡單,在@Configuration注解的類里面,@Bean我們自定義的攔截器類。比如我們需要注冊自定義的MybatisInterceptor攔截器。
/* * Mybatis配置 * */ @Configuration public class MybatisConfiguration { //注冊攔截器 public MybatisInterceptor mybatisInterceptor(){ MybatisInterceptor interceptor = new MybatisInterceptor(); Properties properties = new Properties(); // 可以調用properties.setProperty方法來給攔截器設置一些自定義參數 interceptor.setProperties(properties); return interceptor; } }
這樣一來,攔截器基本使用就介紹完畢了。
部分內容引用自:https://blog.csdn.net/wuyuxing24/article/details/89343951
