MyBatis源码解析之基础模块—Plugin
前文回顾
上一章节我们一起学习了Mapper接口绑定的源码逻辑。本次我们学习MyBatis的Plugin数据源模块。
架构设计
Plugin模块所在包路径为org.apache.ibatis.plugin
,对应的类架构设计图如下:
源码解读
Signature
Signature注解类主要定义了三个属性,通过这些属性定位对应要拦截的方法。
package org.apache.ibatis.plugin;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 拦截器方法签名注解类
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({
})
public @interface Signature {
/**
* type为执行器类型
*/
Class<?> type();
/**
* 要拦截的方法名
*/
String method();
/**
* 被拦截方法的参数数组列表(切记参数列表的顺序要完全一致)
*/
Class<?>[] args();
}
Intercepts
该注解类只有一个属性,即Signature数组列表。也即是说该注解是一个拦截组合,里面聚合了多个要拦截的方法签名。
public @interface Intercepts {
/**
* 要拦截的方法签名数组
*/
Signature[] value();
}
用于编写的自定义拦截器实现类,其注解格式如下:
@Intercepts({
@Signature(type= Executor.class, method = "update", args = {
MappedStatement.class ,Object.class})})
Signature、Intercepts定义了拦截注解的标志,那mybatis是如何实现拦截的呢?咱们接着往下看。
Invocation
在Mybatis的plugin包中,定义了一个Invocation类,该类有三个属性:target、method、args。看到这三个大家应该似曾相识吧,没错就是与动态代理有关。
同时封装了反射调用的方法。
package org.apache.ibatis.plugin;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Invocation {
private final Object target; //目标对象
private final Method method; //执行方法
private final Object[] args; //方法参数
//构造犯法
public Invocation(Object target, Method method, Object[] args) {
this.target = target;
this.method = method;
this.args = args;
}
/*** target、method、args的get方法 ***/
//代理执行方法
public Object proceed() throws InvocationTargetException, IllegalAccessException {
//反射调用
return method.invoke(target, args);
}
}
Interceptor
Interceptor为自定义的拦截器接口,用户自定义的拦截器都必须实现该接口。该接口及内部方法的具体的说明参考源码注释:
package org.apache.ibatis.plugin;
import java.util.Properties;
/**
* @author Clinton Begin
* 自定义拦截器的接口
* 实现该接口的实现类,需要有注解:
样例:
@Intercepts({@Signature(type= Executor.class, method = "update", args = {MappedStatement.class ,Object.class})})
*/
public interface Interceptor {
//对需要拦截的业务进行增强操