关于Mybatis工程使用 SqlSession 创建 dao 接口的代理对象 — sqlSession.getMapper(target.class)
在练习mybatis项目时,我们对下面这段代码并不陌生初学的我们都只背下了1、先创建 SqlSession 对象2、调用它的 getMapper(target.class) 方法 获取 目标代理对象3、最后就能使用此目标对象 调用 我们想调用的业务了????首先提出问题一:为什么要用 getMapper(target.class) 方法 获取 目标代理对象 ?解答:因为 Java 中 对于 接口类
在练习mybatis项目时,我们对下面这段代码并不陌生
初学的我们都只背下了
1、先创建 SqlSession 对象
2、调用它的 getMapper(target.class) 方法 获取 目标代理对象
3、最后就能使用此目标对象 调用 我们想调用的业务了
🐕首先提出问题一:
为什么要用 getMapper(target.class) 方法 获取 目标代理对象 ?
解答:
因为 Java 中 对于 接口类 是不能直接实例化的。
如果要使用它,就得生成它的实现类,再使用它的实现类来操作接口中的方法, 如下图
但是如果这样子的话 我们就得搞出一大堆 实现类了… 这怎么能行?
所以我们使用反射来动态 生成目标代理对象~
其实刚刚的注释已经很明确的谈到了一项技术:动态代理
getMapper(target.class) 方法通过目标的字节码文件 动态生成 目标对象,我们才可以使用此 目标对象(执行目标对象的方法)
动态代理分为两大类:基于接口的动态代理,基于类的动态代理
不懂动态代理的可以查看往期博文:23种设计模式之结构型模式:代理模式
我们这里使用的就是基于接口的动态代理,通过sqlSession.getMapper(Dao.class) 来生成 dao接口的代理对象
好了 相信看到这里 应该都知道了sqlSession.getMapper(UserDao.class)的作用了
但是我们只是知道他 创建了 dao 接口的代理对象,底层是如何的呢?
下面开始看源码
进入 sqlSession.getMapper()方法
它有两个实现类 我们进入 DefaultSqlSession
可以看到他 调用的是 配置类的 getMapper方法 传入 字节码文件,和 sqlsession
我们点进去 配置类的getMapper 看看
可以看到 配置类中的getMapper 方法 调用的是 mapper注册中心的 getMapper方法
那我们进入mapper注册中心的 getMapper方法 瞧瞧
可以看出 knownMappers 是一个 hashMap
怎么回事 怎么突然就从map中get(type)了 ??? 这时肯定有疑惑?它是什么时候add进去的??
我们往下看 发现一个 addMapper方法
我们肯定明白 他肯定有调用这个addMapper方法 先添加了 可是在哪里添加了呢?
功夫不负有心人 总算被我逮到了!
在创建 sqlSessionFactory 时候 注册的!!!
点进去 build()
又回到最初的起点,呆呆的站在电脑💻前~
所以 在初始化 SqlSessionFactory 时,Mapper接口注册在MapperRegistry类的 hashMap中,其中 键为 Mapper接口的字节码文件,值为 当前Mapper的工厂
害 addMapper部分总算找到了 回归正题 getMapper()部分
心心念念的代码 浮现眼前
我信了 sqlSession.getMapper(dao.class)方法 返回 dao接口的代理对象了!!!
更多推荐
所有评论(0)