MyBatis源码解析——获取Mapper对象

时间:2024-05-21 12:28:34

之前两篇文章,已经讲述了SqlSessionFactorySqlSession的获取过程,那么今天就一起来看一下SqlSession是如何得到Mapper的,从而执行相应的增删改查方法。这里还是以之前的代码为例,一步步debug的方式,去探究其中的过程。

 

MyBatis源码解析——获取Mapper对象

首先,sqlSession调用getMapper(Class<?> type)方法,参数里传入指定的Class类型,返回给我们的就是一个传入该类型的对象,这个对象其实是一个代理对象,后面我们再具体说明一下。进入到getMapper(type)方法后,再次调用configuration.getMapper(type,sqllSession),在Configuration类中,继续调用mapperRegistry.getMapper(type,sqlSession)方法。mapperRegistry是不是有点眼熟,在上次讲解获取SqlSessionFactory中,解析mapper子节点时,我们还记得,将获取的Mapper接口都放在一个knowMappers(其实是一个hashMap)中。在mapperRegistry.getMapper(type,sqlSession)方法中,先从knowMappers取出该type对应的mapperProxyFactory,顾名思义,这是一个mapper代理工厂,后面想想也应该明白,我们需要的对象应该就是从工厂中生成的。接着调用mapperProxyFactory.newInstance(sqlSession)方法,果不其然,先new出一个MapperProxy对象,这个对象看了一下,实现了InvocationHandler接口,这个大家还熟悉吗,jdk的动态代理,而jdk的动态代理就要求被代理的类必须要实现接口,所以mybatis基于接口的实现方式,就是用了jdk的动态代理,这个对象里还有其他一些信息,比如methodCache(方法缓存),下次再探究。继续调用newInstance(mapperProxy)方法,接下来看着,也就是jdk动态代理的获取代理对象的方法:return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);下面就是jdk动态代理方面的东西了,接下来就是验证、优化、缓存、同步、生成字节码、显式类加载等操作。这里就不再详述了,有时间我会专门写一篇文章和大家聊聊jdk的动态代理。就这样我们就得到了Mapper的代理对象,这里我给它打印出来了:userMapper全名: class com.sun.proxy.$Proxy2,可以看出来代理类有个$符号,mybatis就是通过这个代理对象去执行对应的增删改查方法。附一张时序图,如图所示。

MyBatis源码解析——获取Mapper对象

 

到这里就大概了解了Mapper对象的获取过程,下一次和大家聊一下mybatis执行增删改查的详细过程