天天看點

mybatis随筆三之SqlSession

在上一篇文章我們已經得到了DefaultSqlSession,接下來我們對sqlSession.getMapper(DemoMapper.class)這種語句進行分析      
@Override
  public <T> T getMapper(Class<T> type) {
    return configuration.<T>getMapper(type, this);
  }      
在這裡又調用了如下方法      
public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
    return mapperRegistry.getMapper(type, sqlSession);
  }      
getMapper方法代碼如下      
@SuppressWarnings("unchecked")
  public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
    final MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) knownMappers.get(type);
    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);
    }
  }      
在SqlSessionFactoryBuilder建立SqlSessionFactory的過程中已經将mapper接口到了knownMappers中,找不到的話這裡會抛錯。      
public T newInstance(SqlSession sqlSession) {
    final MapperProxy<T> mapperProxy = new MapperProxy<T>(sqlSession, mapperInterface, methodCache);
    return newInstance(mapperProxy);
  }      
首先執行個體化一個MapperProxy對象,我們對Mapper接口的調用實際上使用的MapperProxy對象,mapperInterface在build factory的過程中已經設定過值了,methodCache後面會提,暫時不提。      
protected T newInstance(MapperProxy<T> mapperProxy) {
    return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);
  }      
從這裡可以得知我們傳回的mapper對象實際是個代理對象。      
mybatis随筆三之SqlSession
由debug可清晰的看到傳回的mapper對象是由jdk代理生成。      
至此SqlSession的getMapper方法分析結束。