Spring 整合Mybatis源码分析 学习笔记

Mybatis-Spring 学习笔记


先进到这个类里面看看
分别实现了这三个类FactoryBean, InitializingBean, ApplicationListener
在这里插入图片描述
因为实现了InitializingBean里的void afterPropertiesSet() throws Exception;方法, 所以会执行到这里

最终调用里面的buildSqlSessionFactory()方法,继续往下看:

首先是判断在配置文件里面有没有配置configuration(这里我没有配置)
直接执行到后面else
在这里插入图片描述
因为没有配置configuration所以直接new了一个,再设置属性

后面一大篇就是检测判断是否配置里面的一些配置(大部分都不用配)
下面就说些常用的
在这里插入图片描述

这个是判断是否配置插件的在这里插入图片描述
是否设置缓存
在这里插入图片描述
下面这个就是检测mapperLocations, 最终是通过 xmlMapperBuilder.parse();这个方法来进行解析的在这里插入图片描述进入到这个方法,发现这个方法是mybatis包里面的方法,通过configurationElement(parser.evalNode("/mapper"));这个方法来解析mapper配置文件在这里插入图片描述
解析完成之后返回了一个sqlSessionFactory对象
在这里插入图片描述
再进到build()方法看一下,这里实际上返回的是DefaultSqlSessionFactory对象
在这里插入图片描述

所以这里的buildSqlSessionFactory()这个方法的实际作用就是:
1,解析了配置文件(dataSource mapperLocation)
2,将mapper.xml放到了MappedStatement这个集合中
3,返回了一个DefaultSqlSessionFactory对象

所以最开始的afterPropertiesSet()这个方法就是把得到的defaultSqlSessionFactory赋值给sqlSessionFactory

那么下面的getObject()方法就是获取这个sqlSessionFactory
在这里插入图片描述
默认单例的在这里插入图片描述

再来看第二个类:
在这里插入图片描述
先分析这个类实现的接口
在这里插入图片描述
BeanDefinitionRegistryPostProcessor : 这个接口是Spring中的,就是一个beanDefinition的后置处理器,其实这个类就是在对象生成BeanDefinition还没有放入IOC容器的时候对这个类进行干预的接口,里面提供了一个回调的方法,通过这个方法就可以修改bean的定义
在这里插入图片描述
InitializingBean: 这个接口里面也只提供了一个方法,是在把对象放到IOC容器之后的回调方法, 对象创建完成之后进行值的设置
在这里插入图片描述
主要就是上面这两个方法; 先来分析第一个,把对象放到IOC容器前都干了些什么在这里插入图片描述下面就是读取并配置我们的配置信息, 最后调用scan()方法,所以进入scan()方法
在这里插入图片描述
发现scan()方法里面调用了doScan()方法,并且把扫描的包路径传了进去
进入doScan()方法,注意,这里进入的是中间包里面的ClassPathMapperScanner这个类里面(Spring的包)的doScan()方法,扫面自己的文件,因为Spring里面自己定义了要扫描那些注解
进到这个方法里面首先调用的是父类里面的doScan方法获取到所有的BeanDefinition的定义(就是所有类的定义),这里扫描的是所有的mapper接口, 下面进行if判断当beanDefinitions不为空(意思是扫描到有mapper接口),就执行processBeanDefinitions()这个方法,在这个方法里面完成bean的定义
在这里插入图片描述执行到这里首先咱们翻译下这个注释:意思就是说本来要放到IOC容器的bean是mapper的这个接口, 但是实际上放到IOC容器的是MapperFactoryBean这个类的对象,也就是说实际上放到容器的是mapper的工厂对象
在这里插入图片描述
所以首先就遍历上一个方法里面得到每个的类的描述对象,通过这句代码definition.setBeanClass(this.mapperFactoryBean.getClass());设置bean描述对象的class对象为bean的工厂对象
后面的代码就是将刚刚读取到的配置文件的信息设置到beanDefinition里面,
在这里插入图片描述 最后设置了自动注入的模型为通过类型注入

那么既然放到IOC容器的是MapperFactoryBean的对象,那么下面到这个类里面看看
在这里插入图片描述实现了FactoryBean这个接口,FactoryBean这个接口里面有三个方法分别是:T getObject() throws Exception; 得到工厂创建的实例对象
Class<?> getObjectType(); 得到创建的这个实例的类型
boolean isSingleton(); 这个对象是否是单例的

这里就得出结论: 继承了SqlSessionDaoSupport这个方法目的是为了获取里面的getSqlSession()方法,实现FactoryBean的目的就是为了返回当前MapperFactoryBean中的一个实例

private Class mapperInterface; 这个属性就是mapper接口的全路径

MapperFactoryBean中的这个方法就是调用了父类中的getSqlSession()获取sqlSession对象来获取mapper对象
在这里插入图片描述这里我们再来看看这个方法里面, 是通过sqlSession.getMapper来获取实例,
先看看这个getSqlSession()获取到的到底是什么在这里插入图片描述再往下看在这里插入图片描述所以说这里得到的sqlSession对象是SqlSessionTemplate而不是DefaultSqlSession, 那么就有一个疑问,为什么这里不使用DefaultSqlSession呢?再进入SqlSessionTemplate(sqlSessionFactory);这个构造器一探究竟
最终调用了两个构造器进入到如下方法, 发现了什么…这个SqlSessionTemplate对象,实际上就是一个代理对象, 这里代理的就是defaultSqlSession这个对象 .在这里插入图片描述回到刚刚那个问题为什么不直接使用defaultSqlSession这个对象呢,我们进到DefaultSqlSession看一看, 这里作者写的很清楚,这个类是线程不安全的, 从下面的成员变量也可以看出来这个类是线程不安全的, 因为放到IOC容器中的类默认是单例的, 那么单例的就一定存在线程安全问题, 所以这里使用SqlSessionTemplate来保证放到IOC容器中的对象是线程安全在这里插入图片描述
再来看一下SqlSessionTemplate这个类, 从作者的注释和下面的属性都是静态常量,所以SqlSessionTemplate是线程安全的 ,
在这里插入图片描述再回到上面,如下图所示,那么既然SqlSessionTemplate是线程安全的,为什么不直接返回这个类的对象, 而是使用动态代理返回DefaultSqlSession的代理对象呢
在这里插入图片描述下面来看一下这个动态代理类在执行方法的时候都干了些什么,先进到new SqlSessionInterceptor()这个方法里面(最终动态代理执行的方法)在这里插入图片描述看看怎么获取这个SQLSession的在这里插入图片描述那么再看看这个持有器都干了什么,进到getResource(sessionFactory)这个方法在这里插入图片描述
再进到doGetResource(actualKey)方法里在这里插入图片描述所以来看看这个resources在这里插入图片描述这里使用了ThreadLocal来储存这个map, 而map中放的是defaultSqlSession的持有器, 这里使用ThreadLocal来唯一标记一个线程,用来保证defaultSqlSession的持有器的线程是安全的同时就保证了一个ThreadLocal里面只有唯一一个defaultSqlSession, (就相当于每个线程来的时候分配了一个属于自己的defaultSqlSession)

这里回到刚刚那个方法, 获取到持有器后通过持有器和executorType(执行器,这个执行器是最后用来执行SQL语句用的)获取到defaultSqlSession ,在这里插入图片描述
前面说到过,实际上放到单例池的是mapperFactoryBean这个对象,那么我们为您看看这个工厂对象是怎么实例化mapper的,首先进到这个类,发现这俄格类是实现了FactoryBean的,在这里插入图片描述来看看这个工厂怎么获取对象的在这里插入图片描述这里实际上就是调用了mybatis里面的getMapper()方法,而这个getMapper方法返回的就是mapper接口的代理对象,最终在myBatis的方法里面执行操作数据库。就成功的连接了mybatis和spring

仅个人学习笔记,如有不足,还有劳各路大佬多多指教~

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring整合Mybatis源码分析可以分为以下几个步骤: 1. 创建Spring容器并加载配置文件。在Spring Boot中,可以通过@SpringBootApplication注解来创建Spring容器,并在配置文件中配置Mybatis相关的属性。 2. 创建Mybatis的SqlSessionFactory。Spring Boot会自动配置Mybatis的SqlSessionFactory,通过读取配置文件中的数据源信息和Mybatis的配置信息,创建SqlSessionFactory对象。 3. 注册Mybatis的Mapper接口。Spring Boot会自动扫描项目中的Mapper接口,并将其注册到Spring容器中。 4. 创建Mapper代理对象。Spring Boot使用Mybatis的MapperFactoryBean来创建Mapper接口的代理对象。在创建代理对象时,会使用SqlSessionFactory来创建SqlSession,并将SqlSession注入到Mapper接口中。 5. 使用Mapper代理对象进行数据库操作。通过调用Mapper接口的方法,可以实现对数据库的增删改查操作。 整个过程中,Spring Boot通过自动配置和注解扫描的方式,简化了Spring整合Mybatis的配置和使用过程,使得开发者可以更方便地使用Mybatis进行数据库操作。\[1\]\[2\]\[3\] #### 引用[.reference_title] - *1* [SpringBoot整合Mybatis源码解析](https://blog.csdn.net/u013521882/article/details/120624374)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [Spring-Mybatis整合源码分析](https://blog.csdn.net/qq_42651904/article/details/111059652)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [Spring源码解析之整合Mybatis](https://blog.csdn.net/heroqiang/article/details/79135500)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值