boundSql = ms.getBoundSql(parameter);
cacheKey = executor.createCacheKey(ms, parameter, rowBounds, boundSql);
} else {
cacheKey = (CacheKey)args[4];
boundSql = (BoundSql)args[5];
}
System.out.println(“Interceptor1”);
List resultList = executor.query(ms, parameter, rowBounds, resultHandler, cacheKey, boundSql);
return resultList;
}
}
@Intercepts({@Signature(
type = Executor.class,
method = “query”,
args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}
), @Signature(
type = Executor.class,
method = “query”,
args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class}
)})
public class Interceptor2 implements Interceptor {
@Override
public Object intercept(Invocation invocation) throws Throwable {
Object[] args = invocation.getArgs();
MappedStatement ms = (MappedStatement)args[0];
Object parameter = args[1];
RowBounds rowBounds = (RowBounds)args[2];
ResultHandler resultHandler = (ResultHandler)args[3];
Executor executor = (Executor)invocation.getTarget();
CacheKey cacheKey;
BoundSql boundSql;
if (args.length == 4) {
boundSql = ms.getBoundSql(parameter);
cacheKey = executor.createCacheKey(ms, parameter, rowBounds, boundSql);
} else {
cacheKey = (CacheKey)args[4];
boundSql = (BoundSql)args[5];
}
System.out.println(“Interceptor2”);
List resultList = executor.query(ms, parameter, rowBounds, resultHandler, cacheKey, boundSql);
return resultList;
}
}
其他配置和一文看懂mybatis底层运行原理解析这篇里面的一样。
首先我们看获取SqlSession的方法
不多做解释,直接看到org.apache.ibatis.session.defaults.DefaultSqlSessionFactory#openSessionFromDataSource方法的74行:
继续往下看 newExecutor 方法的579行:
继续看org.apache.ibatis.plugin.InterceptorChain#pluginAll方法:
可以看到这里会去遍历 interceptors 这个集合。那么 interceptors 这个属性是什么时候初始化的呢?
是在构造 SqlSessionFactory 时初始化的,继续往下 会看到 org.apache.ibatis.builder.xml.XMLConfigBuilder#parseConfiguration 这个方法
上图中可以看到初始化 mybatis-config.xml 时,会解析其中的plugin属性,然后放到 org.apache.ibatis.plugin.InterceptorChain#interceptors 中。
继续看 interceptor 主流程的执行:
上图中可以看到 Interceptor 接口中的 plugin 方法都有一个默认实现:org.apache.ibatis.plugin.Plugin#wrap 方法
继续看 getSignatureMap 方法:
这段代码主要就是获取 Interceptor 实现类上的注解信息,结合 Interceptor1 上注解可以知道,最后 signatureMap 中存储的信息就是key为 Executor.class,value为Executor接口中的2个query方法。
继续看 getAllInterfaces 方法:
代码中能看到会循环遍历type类的父接口,然后判断signatureMap是否包含此类,结果会返回signatureMap中key包含的接口类,也就是Executor接口了。
继续往下看 Proxy.newProxyInstance 方法:
这行代码就用到了动态代理设计模式了,不熟悉的同学可以先去看看我的白话解析动态代理设计模式。
结果就是会根据mybatis-config.xml中配置的拦截器数量来生成代理类,最后都会去调用org.apache.ibatis.plugin.Plugin#invoke方法
上图中就会去执行自定义Interceptor中的 intercept 方法了。
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
1200页Java架构面试专题及答案
小编整理不易,对这份1200页Java架构面试专题及答案感兴趣劳烦帮忙转发/点赞
百度、字节、美团等大厂常见面试题
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
cgfQoUm-1713751594270)]
[外链图片转存中…(img-542YEDzD-1713751594270)]
百度、字节、美团等大厂常见面试题
[外链图片转存中…(img-YDdDhUE0-1713751594270)]
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!