type
status
date
slug
summary
tags
category
icon
password
😀
这里写文章的前言: 一个简单的开头,简述这篇文章讨论的问题、目标、人物、背景是什么?并简述你给出的答案。
可以说说你的故事:阻碍、努力、结果成果,意外与转折。
 

📝 题记

MyBatis 与 Spring 整合操作. 在我们入门学习 SSM 等东西的时候,就发现了任何东西,最后都是逃不过与Spring整合起来的道路. 然后这里看完 MyBatis 整合完 Spring 之后,那么之后一些其他的第三方,比如axon/redis/apollo/shiro 等这些东西,如果要整合 Spring 的时候,是不是也是相似的整合方式呢?
这个需要我们看完 MyBatis 与 Spring 之后,探究其整合的操作.
 

入门

分几个步骤,操作一把即可,带你回到哪个 SM 时代,不过这回是没有了 tomcat 的.
先放上一个完成的整合地址 : https://github.com/baoyang23/mybtatis-analysis/tree/master/mybatis-spring-hello 如果不要看下面流程的,一步跳过即可.
  1. 先创建一个 maven 项目,引入依赖. 依赖参考地址 : https://github.com/baoyang23/mybtatis-analysis/blob/master/mybatis-spring-hello/pom.xml
  1. db配置 : https://github.com/baoyang23/mybtatis-analysis/blob/master/mybatis-spring-hello/src/main/resources/db.properties
  1. MyBatis配置: https://github.com/baoyang23/mybtatis-analysis/tree/master/mybatis-spring-hello/src/main/resources/mybatis
  1. Spring 配置: https://github.com/baoyang23/mybtatis-analysis/blob/master/mybatis-spring-hello/src/main/resources/spring-beans.xml
  1. 最后,来份我们熟悉的 https://github.com/baoyang23/mybtatis-analysis/tree/master/mybatis-spring-hello/src/main/resources/sql mapper.xml 文件.
  1. 不忘记再来一份代码 : https://github.com/baoyang23/mybtatis-analysis/tree/master/mybatis-spring-hello/src 这些直接跑测试类即可.
跟着这上面的几个步骤,就可以搭建完一个项目. 然后喊上我们的 永哥, 打上传说中的 debug , 疯狂的调试看每步干了什么事.
这个的时候,可以跑下测试类,是ok的.
 

分析

这里我们首先想到的是我们引入的依赖,是不是有个 mybatis-spring 的依赖. 从这个依赖,可以很明显的看出来,就是通过这个依赖,将 MyBatis 和 Spring 整合起来的。
然后再想想,我们除了这个依赖的话,还再哪里有使用到一些 Spring 和 MyBatis 的东西呢? 然后看到 spring-beans.xml 这个xml配置, 可以看到 org.mybatis.spring.SqlSessionFactoryBean 给注入到 bean 里面来了.org.mybatis.spring.mapper.MapperScannerConfigurer也是给注入到 bean 里面来了. 并且二者都有通过来进行属性设置值操作.
那么,我们就基于这二个类的源码开始阅读.
 

方法阅读

SqlSessionFactoryBean (org.mybatis.spring.SqlSessionFactoryBean)

这里 SqlSessionFactoryBean 是实现了很多接口,这些接口都是Spring的.
FactoryBean 工厂bean,点进去可以看到,其有方法getObject()/getObjectType等方法获取bean的,然后加上泛型,也就是这里获取的 getObject就是泛型.
InitializingBean: afterPropertiesSet 初始化 bean 的时候,会调用该方法.
ApplicationEvent: Spring的事件传播机制,就是使用的这种方式.
 

org.mybatis.spring.SqlSessionFactoryBean#buildSqlSessionFactory

该方法需要单独拿出来说下,因为内容还是比较多的.
可以看到该方法给人感觉, 先是判断一些配置信息是不是有值,如果是有值的话,就会进行相应的处理。最后调用我们在看单个 mybatis 的 parse 解析方法,最后new了一个默认的sqlSessionFactory工厂类出来.
 

MapperScannerConfigurer(org.mybatis.spring.mapper.MapperScannerConfigurer)

接着看,spring-beans.xml 里面的第二个配置.
可以看到该类,也是实现了 spring 的很多接口.
BeanDefinitionRegistryPostProcessor : 注册BeanDefinition到Spring容器中来.
ApplicationContextAware : 获取 ApplicationContext
BeanNameAware : 设置 beanName名字.
这里也可以按照上面的笨方法,一次对重写的方法打上断点. 然后开启我们的debug来看看方法的执行顺序.
其执行顺序 : setBeanName —> setApplicationContext —> afterPropertiesSet —> postProcessBeanDefinitionRegistry , 跟着这四个方法执行的顺序来看.
赋值给 beanName 值. org.mybatis.spring.mapper.MapperScannerConfigurer#0
所以到这里, 可以看到 MyBatis 与 Spring 整合的过程就已经完成了.
我们这里是主要对 SqlSessionFactoryBean 和 MapperScannerConfigurer 来进行分析的, 可以很明显的感觉到,我们是配置好这二个bean后,就可以使用了. 着重看第二个, org.mybatis.spring.mapper.MapperScannerConfigurer 这个bean,就是做了如何将 MyBatis 的 mapper接口文件给加载到 Spring 中来的. 那么这里我在想, 如果有天我自己开发出一个好用的框架来,要与 Spring 进行整合的话,是不是也这样整合就可以了?
 

🤗 总结归纳

可以看到 MyBatis 与 Spring 整合后, 对于解析 MyBatis 的 mapper 配置文件等,都是走的之前单个 mybatis 的逻辑, 是没有什么变化的. 主要的是将 , SqlSessionFactory 和 Mapper.class(接口类) 给注入到 Spring 容器中.然后接口的话, 是怎么使用的代理类来进行实例化完后, 将对象给注入到 Spring 容器中的呢 ? 这里看 org.mybatis.spring.mapper.MapperScannerConfigurer 做的事情就明白了.
不过在看 mybatis 与 Spring 整合的时候, 还是建议要有对 BeanDefinitionRegistryPostProcessor / InitializingBean / ApplicationContextAware / BeanNameAware 有一定的了接. 就是有了了解后, 你就会很明显的感受到, mybatis 为什么是实现这个接口,实现这个接口并且重写这个方法,在后面是什么时候被调用的. 意思也就是,你至少得明白点 Spring 对外提供的一些扩展点,才能很好的理解这些东西.

📎 参考文章

 
💡
有关文章的问题,欢迎您在底部评论区留言,一起交流~