DefaultSqlSession调用 getMapper时依次调用了片段1,2,3。
我们可以在片段3中看,先是获取到一个MapperProxyFactory对象工厂,然后创建并返回了一个Mapper的代理对象
sqlSession.getMapper(IUserMapper.class);
代码片段1
DefaultSqlSession. getMapper()
public <T> T getMapper(Class<T> type) {
return configuration.getMapper(type, this);
}
代码片段2
Configuration. getMapper()
public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
return mapperRegistry.getMapper(type, sqlSession);
}
代码片段3
MapperRegistry. getMapper()
public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
// 获得 MapperProxyFactory 对象
final MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) knownMappers.get(type);
// 不存在,则抛出 BindingException 异常
if (mapperProxyFactory == null) {
throw new BindingException("Type " + type + " is not known to the MapperRegistry.");
}
/// 通过动态代理工厂生成实例。
try {
return mapperProxyFactory.newInstance(sqlSession);
} catch (Exception e) {
throw new BindingException("Error getting mapper instance. Cause: " + e, e);
}
}
2、MapperProxyFactory会创建一个怎么的代理对象?往下看.
newInstance方法里创建了一个MapperProxy对象,并调用重载方法,使用jdk动态代理,将创建的MapperProxy对象作第三个参数,创建了一个代理对象。
MapperProxyFactory.java
protected T newInstance(MapperProxy<T> mapperProxy) {
return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[]{mapperInterface}, mapperProxy);
}
//MapperProxyFactory类中的newInstance方法
public T newInstance(SqlSession sqlSession) {
// 创建了JDK动态代理的invocationHandler接口的实现类mapperProxy
final MapperProxy<T> mapperProxy = new MapperProxy<>(sqlSession, mapperInterface, methodCache);
// 调用了重载方法
return newInstance(mapperProxy);
}
3、大家都知道,代理对象调用方法,其实都调用第三个参数中实现的invoke()方法。
所以我们看MapperProxy.invoke()方法,实际上是调用了mapperMethod.execute()方法。然后点进去看,你就发现就是调用DefaultSqlSession的selectList等方法。这样就和DefaultSqlSession的增删查改联系起来了。
MapperProxy.invoke()
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try {
// 如果是 Object 定义的方法,直接调用
if (Object.class.equals(method.getDeclaringClass())) {
return method.invoke(this, args);
} else if (isDefaultMethod(method)) {
return invokeDefaultMethod(proxy, method, args);
}
} catch (Throwable t) {
throw ExceptionUtil.unwrapThrowable(t);
}
// 获得 MapperMethod 对象
final MapperMethod mapperMethod = cachedMapperMethod(method);
// 重点在这:MapperMethod最终调用了执行的方法
return mapperMethod.execute(sqlSession, args);
}
mapperMethod.execute()
public Object execute(SqlSession sqlSession, Object[] args) {
Object result;
//判断mapper中的方法类型,最终调用的还是SqlSession中的方法
switch (command.getType()) {
case INSERT: {
// 转换参数
Object param = method.convertArgsToSqlCommandParam(args);
// 执行 INSERT 操作
// 转换 rowCount
result = rowCountResult(sqlSession.insert(command.getName(), param)
break;
}
case UPDATE:
case DELETE:
case SELECT:
case FLUSH:
default:
throw new BindingException("Unknown execution method for: " + comma
}
return result;
}