您的位置:首页 > 移动开发

mybatis源码学习之执行过程分析(3)——mapper接口的获取

2017-01-07 00:46 796 查看
mybatis源码学习之执行过程分析(1)——SqlSessionFactory及SqlSession的创建中,跟踪到
openSession()
方法返回了DefaultSqlSession,并持有Configuration的引用(Configuration的实例化见mybatis源码学习——Configuration类及其初始化过程、TypeHandler、TypeAlias)。

当我们通过
session.getMapper(UserMapper.class)
获取Mapper接口时,其实调用了Configuration中的
getMapper()
方法。

回过头来看我们的代码:

SqlSession session = sqlSessionFactory.openSession();
UserMapper userMapper = session.getMapper(UserMapper.class);


DefaultSqlSession.java

public <T> T getMapper(Class<T> type) {
return this.configuration.getMapper(type, this);
}


可以看到是调用了Configuration中的getMapper()方法。在这里是因为Mapper信息保存在MapperRegistry中的
final Map<Class<?>, MapperProxyFactory<?>> knownMappers = new HashMap()
中(详细过程见Configuration的实例化和xml的解析的分析)。

Configuration.java

public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
return this.mapperRegistry.getMapper(type, sqlSession);
}


MapperRegistry.java

public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
//在这里拿到了Mapper接口所在代理工厂
MapperProxyFactory mapperProxyFactory = (MapperProxyFactory)this.knownMappers.get(type);
if(mapperProxyFactory == null) {
throw new BindingException("Type " + type + " is not known to the MapperRegistry.");
} else {
try {
return mapperProxyFactory.newInstance(sqlSession);
} catch (Exception var5) {
throw new BindingException("Error getting mapper instance. Cause: " + var5, var5);
}
}
}

protected T newInstance(MapperProxy<T> mapperProxy) {
return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);
}

public T newInstance(SqlSession sqlSession) {
final MapperProxy<T> mapperProxy = new MapperProxy<T>(sqlSession, mapperInterface, methodCache);
return newInstance(mapperProxy);
}


可以看到就是对HashMap的get()操作,并转换为MapperProxyFactory。

至此我们就拿到了UserMapper接口。因为它被MapperProxyFactory中的mapperInterface所引用,获取过程如下图:





public class MapperProxyFactory<T> {

private final Class<T> mapperInterface;
private final Map<Method, MapperMethod> methodCache = new ConcurrentHashMap<Method, MapperMethod>();
...
}


总结

至此mapper接口的获取就结束了,可以看到实质上拿到的是一个MapperProxy代理类。

下面继续分析接口中方法的调用(即代理的调用)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐