spring-整合mybatis源码注解的方式--简单解析

现在主流的spring整合mybatis用注解@MapperScan("com.cat.mapper")

这个注解里包含了注解@Import(MapperScannerRegistrar.class)

在spring源码那篇讲到.扫描到注解@import的时候.会处理里面的class

这里的MapperScannerRegistrar implements ImportBeanDefinitionRegistrar ;所以 spring会去运行实现接口的重写方法;

图1:解析注解@mapperscan,封装到annotationattribute对象里.

图2:然后用classpathbeandefinitonsacn.scan(方法解析扫描的包

图3: 这个scan方法先调用父类去把包下面的所有class添加到bean工厂的beandefinitionmap中.并且返回所有的beandefinition(bd);接着调用processbean....()方法处理这些bd,跟踪该方法

图4:处理bd方法把所有的bd的class都设成了mapperfactorybean;

因此后期再创建bean对象的时候,其实是会创建中出mapperfactorybean的类型.而这个类实现了factorybean接口.所以真正的类型是实现该接口的getobject()方法的返回值:

接下来是重点的地方:

其中该类型继承了一个类,这个类点进去发现其实

SqlSessionDaoSupport extends DaoSupport implements InitializingBean 

而其中 InitializingBean 的重写方法afterPropertiesSet这个方法是在bean初始化后执行;这个方法会执行子类的实现方法checkdaoconfig()-如上图;作用是把该类的包名+类名+方法名作为id.和对应的方法sql等属性分装到对象MappedStatement中.

然后把该对象放到configuration对象的一个map中key为包名+类名+方法名作为id,value 为MappedStatement;

这里的getsqlsession()是spring用了bytype自动装配初始化的对象叫sqlsessiontemplate.如果mybatis没交给spring管理的话创建的是defaultsqlsession;这两个对象的区别非常重要,spring创建失去了session对象使得mybatis的一级缓存失效.看源码可以知道每次的执行sql都会在finally里吧该sqlsession关闭了.(为什么spring要自己关闭,因为没提供向外暴露扩展进行手动关闭).而mybatis的defultsqlsession是不会关闭的.所以一级缓存是有效的;

下面的逻辑是调用mapper方法的时候的逻辑:

跟中代码到这个.发现.用到了jdk动态代理.生成代理对象.且mapperproxy这个类为具体方法实现,继续跟踪这个类的invok方法.

这里.不展开了.比较复杂.基本上是获取到对象mappermethod.该对象包含了该方法的执行sql对象以及返回类型.这信息都是从mappstament对象里拿到的.最后执行execute.里面判断语句方式,.返回类型等.

最后执行该语句.是把sqlsessiontemplate做了个代理对象.,然后执行该代理对象的invoke方法.该方法里就会把sqlsession关闭.从而使一级缓存失效;

(mybatis的二级缓存虽然是跨sqlsession对象的但是只能在同一个命名空间里.,也就是如果其他空间有对数据进行修改.那么这时候查出来的sql还是用该空间的缓存,会脏读.不建议使用,)

总结:

 mybatis给spring管理的话,在bean初始化的时候会把sql的信息和方法关系存起来.然后生成了一个代理对象,

然后在调用方法的时候,如query(),该代理对象又会为其从新创建一个sqlsessionproxy代理对象,进行运行sql.且该代理对象最后关闭sqlsession.

 

有问题的话.希望大佬评论.....谢谢O(∩_∩)O谢谢

 

 

 

 

 

 

 

 

 

 

 

efdfd 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值