Fork me on GitHub

Mybatis拦截器的使用

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

posted @ 2021-01-04 10:01  叶语婷  阅读(2581)  评论(0编辑  收藏  举报