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

来源:互联网 发布:公章可以在淘宝上刻吗 编辑:程序博客网 时间:2024/06/10 19:14

在 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.javapublic <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.javapublic <T> T getMapper(Class<T> type, SqlSession sqlSession) {    return this.mapperRegistry.getMapper(type, sqlSession);}
MapperRegistry.javapublic <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代理类。

下面继续分析接口中方法的调用(即代理的调用)。

0 0