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

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代理类。

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值