代理Dao执行过程
1 | // 读取配置文件,生成字节输入流 |

首先进入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) 通过一个代理工厂返回一个代理对象。

来看看这个代理工厂内部做了啥子:
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方法,然后返回结果的第一个

完整过程图
