【基本思路】拦截器在哪里拦截?什么情况下才会拦截代理?怎么代理呢?只要搞清楚这些,基本的拦截器功能也
3拦截器实现原理
mybatis支持拦截器,实现的原理就是利用JDK的动态代理。
拦截器在哪里呢?mybatis到底提供几处可以拦截呢?请看下图,通过分析源码可知基本查询流程如下:
【简洁的流程】 首先mybatis初始化加载的时候,利用 MapperProxy代理 自己的Mapper接口类, 生成一个代理处理类,代理处理的逻辑都在 invoke方法里,首先获取到目标类的接口 declaringInterface,然后生成 MapperMethod,(其中 sqlSession是 SqlSessionTemplate,是spring连接mybatis的模板类,是由spring负责生成的),生成了 MapperMethod,直接调用 MapperMethod可执行的方法 execute就能获取执行结果,整个流程非常简洁,非常和spring3 mvc的servlet实现类似,也就是说, MapperMethod就是一个命令,执行命令获取执行结果,也就是标准的命令模式。整个流程代码如下
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
首先mybatis初始化加载的时候,利用 MapperProxy代理 自己的Mapper接口类, 生成一个代理处理类
final Class<?> declaringInterface = findDeclaringInterface(proxy, method);
final MapperMethod mapperMethod = new MapperMethod(declaringInterface, method, sqlSession);
final Object result = mapperMethod.execute(args);
if (result == null && method.getReturnType().isPrimitive()
&& !method.getReturnType().equals(Void.TYPE)) {
throw new BindingException(
"Mapper method '" + method.getName() + "' (" + method.getDeclaringClass()
+ ") attempted to return null from a method with a primitive return type ("
+ method.getReturnType() + ").");
}
return result;
}