您当前的位置: 首页 >  mybatis

止步前行

暂无认证

  • 2浏览

    0关注

    247博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

MyBatis工作原理源码分析(三)——获取接口的代理对象(MapperProxy)

止步前行 发布时间:2019-02-18 13:13:31 ,浏览量:2

一、引言

手动使用Mybatis的四个步骤:

获取SqlSessionFactory对象
获取sqlSession对象
获取接口的代理对象(MapperProxy)
执行增删改查方法

MyBatis工作原理源码分析(一)——SqlSessionFactory的初始化 MyBatis工作原理源码分析(二)——获取SqlSession对象 前两篇详细分析了第一步和第二步,下面在此基础上,继续来分析接口的代理对象(MapperProxy)的获取。

二、源码分析

再次说明:我们知道,在第二步中,获得了SqlSession(默认实现是DefaultSqlSession)。该SqlSession中包括执行具体Sql的Executor和保存全局配置信息的Configuration。

// 3、获取接口的实现类对象
//会为接口自动的创建一个代理对象,代理对象去执行增删改查方法,传入接口名
DepartmentMapper mapper = openSession.getMapper(DepartmentMapper.class);
Department dept = mapper.getDeptById(1);
1、调用SqlSession的getMapper()方法
//调用的是Configuration的getMapper()方法,参数type为传入的接口全类名
//什么都不做,直接去configuration中找
@Override
public  T getMapper(Class type) {
  return configuration.getMapper(type, this);
}
2、SqlSession把包袱甩给了Configuration,接下来就看看Configuration
//在Configuration中,又调用了MapperRegistry的getMapper()方法
public  T getMapper(Class type, SqlSession sqlSession) {
	//烫手的山芋,俺不要,你找mapperRegistry去要
  return mapperRegistry.getMapper(type, sqlSession);
}
3、Configuration也不要这烫手的山芋,接着甩给了MapperRegistry, 那咱看看MapperRegistry。
//MapperRegistry中的getMapper()方法
public  T getMapper(Class type, SqlSession sqlSession) {
   //能偷懒的就偷懒,俺把粗活交给MapperProxyFactory去做
   final MapperProxyFactory mapperProxyFactory = (MapperProxyFactory) knownMappers.get(type);
   if (mapperProxyFactory == null) {
     throw new BindingException("Type " + type + " is not known to the MapperRegistry.");
   }
   try {
     //关键在这儿,将sqlSession传入,创建一个MapperProxy
     return mapperProxyFactory.newInstance(sqlSession);
   } catch (Exception e) {
     throw new BindingException("Error getting mapper instance. Cause: " + e, e);
   }
}

//MapperProxyFactory中的newInstance()方法,传入SqlSession
public T newInstance(SqlSession sqlSession) {
  final MapperProxy mapperProxy = new MapperProxy(sqlSession, mapperInterface, methodCache);
  return newInstance(mapperProxy);
}
 
protected T newInstance(MapperProxy mapperProxy) {
  //动态代理我们写的dao接口
  return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);
}

MapperRegistry中的knownMappers保存了每一个mapper对应的MapperProxyFactory,如下图。在MapperRegistry中的getMapper()方法中, 所以可以通过全类名从knownMappers中获取得到接口的MapperProxyFactory, 然后用这个MapperProxyFactory创建了接口的代理对象。 在这里插入图片描述

4、调用SqlSession的getMapper()方法的顺序图

在Mybatis中,通过MapperProxy动态代理接口,也就是说,当我们执行自己写的Dao里面的方法的时候,其实是对应的MapperProxy在代理。那么,咱们就看看怎么获取MapperProxy对象: 在这里插入图片描述

三、小结

获取接口的代理对象(MapperProxy)的时序图 在这里插入图片描述

1、getMapper()方法返回接口的代理对象,包含了SqlSession对象; 2、getMapper()方法中,使用MapperProxyFactory创建一个MapperProxy的代理对象,代理对象里面包含了DefaultSqlSession(Executor); 3、openSession.getMapper(DepartmentMapper.class)方法,获取得到的是Mapper接口的代理对象,后面所有对接口的操作,都是代理对象在处理。
关注
打赏
1657848381
查看更多评论
立即登录/注册

微信扫码登录

0.0361s