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