先看一个拦截器例子
- 自定义拦截器功能
@Intercepts( {
@Signature(method = "query", type = Executor.class, args = {
MappedStatement.class, Object.class, RowBounds.class,
ResultHandler.class })})
public class ExamplePlugin implements Interceptor {
public Object intercept(Invocation invocation) throws Throwable {
System.out.println("intercepts begin");
Object result = invocation.proceed();
System.out.println(result);
System.out.println("intercepts end");
return result;
}
public Object plugin(Object o) {
return Plugin.wrap(o, this);
}
public void setProperties(Properties properties) {
String prop1 = properties.getProperty("prop1");
String prop2 = properties.getProperty("prop2");
System.out.println(prop1 + "-----" + prop2);
}
}
- 在配置文件中引入拦截器
<plugins>
<plugin interceptor="com.yongssu.mybatis.demo1.ExamplePlugin">
<property name="prop1" value="prop1"/>
<property name="prop2" value="prop2"/>
</plugin>
</plugins>
- 上面拦截器实现了拦截select查询
在输出查询结果前会输出 “intercepts begin”,在输出查询结果后会输出 “intercepts end”。
Interceptor接口介绍
mabatis提供了一个Interceptor接口,通过实现该接口我们就可以定义我们自己的拦截器。
public interface Interceptor {
Object intercept(Invocation invocation) throws Throwable;
Object plugin(Object target);
void setProperties(Properties properties);
}
这个接口中定义了三个方法:
intercept —— 进行拦截时要执行的方法。
plugin —— 用于封装目标对象,通过改方法我们可以返回目标对象本身,也可以返回它的一个代理。当返回的是代理的时候,我们可以对其中的方法进行拦截来调用intercept方法,当然也可以调用其他方法。
setProperties —— 用于在Mybatis配置文件中指定一些属性。
@Intercepts和@Signature注解
@Intercepts —— 表明当前对象是一个Interceptor。
@Signature —— 表明要拦截的接口、方法以及对应的参数类型。
Plugin类
mybatis在Plugin类中为plugin方法提供了一个实现。在Plugin中有一个wrap方法如下:
public static Object wrap(Object target, Interceptor interceptor) {
Map<Class<?>, Set<Method>> signatureMap = getSignatureMap(interceptor);
Class<?> type = target.getClass();
Class<?>[] interfaces = getAllInterfaces(type, signatureMap);
if (interfaces.length > 0) {
return Proxy.newProxyInstance(
type.getClassLoader(),
interfaces,
new Plugin(target, interceptor, signatureMap));
}
return target;
}
在Plugin中的wrap方法中的执行过程如下:
1.根据当前Interceptor上面的@Interceptor注解定义了哪些接口会被拦截;
2.判断当前目标对象是否有实现对应需要拦截的接口。如果没有则返回对象本身,如果没有则返回一个代理对象。
参考资料:http://elim.iteye.com/blog/1851081
网友评论