代理Dao执行过程
1 | // 读取配置文件,生成字节输入流 |
![](/2020/06/20/mybatis%E4%BB%A3%E7%90%86dao/1592630241162.png)
首先进入DefaultSqlSession类里面的getMapper()f方法
1
2
3
4
public <T> T getMapper(Class<T> type) {
return configuration.<T>getMapper(type, this);
}进入到configuration类中去调用getMapper方法
1
2
3public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
return mapperRegistry.getMapper(type, sqlSession);
}mapperRegistry.getMapper(type, sqlSession) 通过一个代理工厂返回一个代理对象。
![](/2020/06/20/mybatis%E4%BB%A3%E7%90%86dao/1592630806594.png)
来看看这个代理工厂内部做了啥子:
MapperProxyFactory.java
1
2
3
4
5
6
7
8
9
10
11
12
// 动态代理
protected T newInstance(MapperProxy<T> mapperProxy) {
return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy); // mapperProxy代理的对象
}
public T newInstance(SqlSession sqlSession) {
final MapperProxy<T> mapperProxy = new MapperProxy<T>(sqlSession, mapperInterface, methodCache);
return newInstance(mapperProxy); // 调用了上面的newInstance方法
}MapperProxy实现了InvocationHandler接口。重写invoke方法,内部调用被代理类的对应方法。
最后执行这个方法的execute方法,看看这个方法:
可以看到会调用对应的CRUD操作。
调用Dao的findByName方法, 返回一个User对象,所以执行SelectOne方法
里面是调用SelectList方法,然后返回结果的第一个
![](/2020/06/20/mybatis%E4%BB%A3%E7%90%86dao/1592635692160.png)
完整过程图
![](/2020/06/20/mybatis%E4%BB%A3%E7%90%86dao/%E4%BB%A3%E7%90%86dao%E7%9A%84%E6%89%A7%E8%A1%8C%E8%BF%87%E7%A8%8B.png)