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

📝 前提

MyBatis 与 SpringBoot 整合操作. 在这次整合的过程中,再次明白自己毫无疑问的是一个比较手残的同学了.
这里我们是基于 sql 语句写在 xml 里面进行整合的操作.
 

入门

这里说下创建一个 入门 项目的大致流程.
这里是没有引入 web 依赖的 , 直接启动 main 方法 , 然后就可以看到我们查询出来的结果了.
如果你熟悉 SpringBoot 源码的话,就会晓得有一个自动装配的操作.
如果不熟悉的话,那么就只能通过 @MapperScan(basePackages = {“com.iyang.mybatis.springboot.hello.mapper”}) 去看 , 这样有些是依赖自动装配(spring.factories) 中的配置加载的, 所以这里建议在看之前,如果是有一点 SpringBoot 扩展的知识了解是很好的。如果没有怎么办呢?没有就来看我接下来的内容。
其实这个地方你仔细想下,在 MyBatis 与 Spring 整合的时候,通过 xml 的方式给 MyBatis 的bean 已经 mybatis-spring 中自己写的扫描类,最后将扫描出来的 bd 在还没初始化之前,将bd 的beanClass 替换为我们的代理类.
那么,SpringBoot 与 MyBatis 整合的时候,最后要做的事情是不是也是将 MyBatis 的信息注入到 SpringBoot 来呢?只不过,SpringBoot 就不像 Spring 一样了,还将 bean 的信息配置到 xml 文件中.
于是,接下来跟我的阅读&分析来一步一步的往下看.

方法分析

 
关注点一 : 这里我们点入到 org.mybatis.spring.annotation.MapperScan 注解里面来,可以看到有一个 @Import(MapperScannerRegistrar.class) , 于是我们顺手跟进来 : org.mybatis.spring.annotation.MapperScannerRegistrar , 从名字上来,这个类就做了一个扫描mapper并且将mapper注入到Spring容器中来的事情.
关注点二 : 我们从引入进来的依赖来看, mybatis-spring-boot-starter-2.1.2.jar 跟进到 这个包来,可以看到这个包也是引入一些进来. mybatis/mybatis-spring/spring-boot-starter-jdbc 这三个依赖我们应该不是很陌生的,mybatis-spring-boot-autoconfigure主要来看这个。 spring.factories 的作用大家可以去了解下,SpringBoot很多 EnableAutoConfiguration 的配置都是放入在这个里面的,在启动的时候,会去一层一层的去读取 spring.factories 文件的内容。 这里我们主要来看 : org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration 这个类皆可.
 
MyBatis 在 properties 中的配置文件读取 : org.mybatis.spring.boot.autoconfigure.MybatisProperties
可以看到该类上是有: @ConfigurationProperties(prefix = MybatisProperties.MYBATIS_PREFIX)
于是我们一下子就多了二个关注点, 这里我们可以采用之前的 笨方法, 当你对整合流程执行不是很熟悉的话,可以在这二个关注点的重写方法上都打算断点,看下其执行顺序是怎么执行的. 弄清楚了执行流程,就可以跟着流程来一步一步的分析. 从我们打上 debug 开始,往下的执行流程就是一步一步来的,那么就跟着我们debug 的方法来一步一步的分析.
org.mybatis.spring.annotation.MapperScannerRegistrar#registerBeanDefinitions() —> org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration#MybatisAutoConfiguration —> org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration#afterPropertiesSet —-> org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration#sqlSessionFactory —> org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration#sqlSessionTemplate() —->
 

org.mybatis.spring.annotation.MapperScannerRegistrar#registerBeanDefinitions() 方法 :

这里可以总结下 registerBeanDefinitions 方法,该方法就是将 @MapperScan 的注解属性的值给到 : BeanDefinitionBuilder builder, 该builder 里面有bd,bd的beanClass是MapperScannerConfigurer,最后将MapperScannerConfigurer注入到 Spring 容器中来.
 

MyBatisAutoConfiguration() 有参构造函数

这里我们在 MybatisAutoConfiguration 构造函数上打上断点, 可以根据 断点来分析,走完
notion image
面的方法,然后我们点击走到下一个断点来,就会走到 这个 有参构造函数.
如果好奇的话,可以跟踪debug 的堆栈信息,是怎么走到这步来的. 走到这个方法来 : finishBeanFactoryInitialization(beanFactory) 这是最初的入口.
 

org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration#afterPropertiesSet()方法

这里可以看到是对配置文件是否存在进行检验.
 

org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration#sqlSessionFactory 方法

所以这个方法 : 先是new了一个SqlSessionFactoryBean对象,如果你仔细看的话,你会发现这个对象在之前 mybatis-spring 整合的时候,我们通过 xml 配置文件配置进来的,并且同时通过标签给赋值了datasource等信息, 而这里是通过代码,if等判断,来对 SqlSessionFactoryBean 的属性进行set值的. 最后也是创建出一个 SqlSessionFactory 给注入到 Spring 容器中来.
 

org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration#sqlSessionTemplate 方法

该方法是将 SqlSessionTemplate 给注入到 Spring 容器中啦.
 

疑惑点

大家有没有疑惑我们定义的 mapper 接口 好像从这个流程分析下来,并没有提到 ,那么是在上面时候被注入到 Spring 容器中来的呢?
registerBeanDefinitions() 这个方法 , 注入了MapperScannerConfigurer 到 Spring 容器中来了,可以回顾下之前 mybatis 整合 Spring 的时候,我们是通过 xml 配置了这个对象注入到 spring 容器中来的。 那么注入进来的,回调到 org.mybatis.spring.mapper.MapperScannerConfigurer#postProcessBeanDefinitionRegistry 这个方法的时候,就会将扫描并且将我们的mapper接口文件,给注入到 Spring 容器中来的. 然后扫描的包,是根据@MapperScan 解析注解的时候,是有对扫描的包进行解析的.
 

🤗 总结归纳

总结文章的内容
其实 SpringBoot 整合 MyBatis , 我们从二个切入点来分析是怎么整合进来的. 一是 @MapperScan 注解中的 @Import(MapperScannerRegistrar.class) 将 MapperScannerRegistrar 给导入到 Spring 容器中来, 然后MapperSacnnerRegistrar 来讲 org.mybatis.spring.mapper.MapperScannerConfigurer 给注入到 Spring中来,替换了我们之前用 Spring 整合 Mybatis 的时候,通过xml配置文件整合进来.
二是利用 SpringBoot 提供的 spring-boot-autoconfigure + spring.factories() 来 配置自动注入, 这里注入了 MybatisAutoConfiguration 配置类. 然后注入进来的 MyBatis 配置类做了什么事情呢? 可以看到这个类中是有做: 注入了 SqlSessionFactory. SqlSessionFactory 又是怎么注入进来的呢? 可以看到 org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration#sqlSessionFactory 方法是有先创建一个 org.mybatis.spring.SqlSessionFactoryBean 的, 看到 SqlSessionFactoryBean 这个对象,我们就不难想起 Spring + Mybatis 里面的 beans.xml 是将该对象注入到 Spring 容器中来. 这里是直接new的,然后将一些配置属性并满足条件,给set到 SqlSessionFactoryBean 中来,最后调用 org.mybatis.spring.SqlSessionFactoryBean#getObject 方法来获取 SqlSessionFactory.
spring.factories 文件内容
最后从写的案例里面看, MyBatis 整合 SpringBoot 其实都是在 mybatis —> MyBatis + Spring 等一步一步推导上来的,所以这里不难理解,好的技术都是在有需要和时间的沉淀下一步一步成长起来的.

📎 参考文章

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