在练习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接口的代理对象了!!!

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐