MyBatis+Springboot 启动到SQL执行全流程(2)

简介: MyBatis+Springboot 启动到SQL执行全流程

三、流程2 —— 生成代理并暴露

流程1主要是为了做一个准备,扫描Mapper文件并解析保存。但是仅仅这样是不够的,你还需要给系统暴露一个入口,这样别人才能调用该sql,java中,我们总是通过对象来调用放啊,因此这里我们就需要对Mapper接口去生成代理对象了。不过,对象不需要我们手动创建,在mybatis-spring包中,mybatis已经对结合Spring的场景做了处理,会自动扫描并创建代理,并存储进spring容器中。


1. 扫描Mapper并创建Bean定义

同扫描xml文件一样,这也需要指定扫描的Mapper接口的位置

99b3f731adda4c7ea54192244bfd0508.png

然后就到了一个重点类: MapperScannerConfigurer,我们都知道,Spring启动的核心方法是Refresh,而其中有一步就是调用各工厂后置处理器

d39656ae6a304d97b2149f3d73043726.png

而 MapperScannerConfigurer 实现了 BeanDefinitionRegistryPostProcessor 接口,BeanDefinitionRegistryPostProcessor 继承自工厂后置处理器(BeanFactoryPostProcessor),所以,其在这一步内会被调用,最终的结果就是执行扫描方法

a574cd8633964fbfae30f264945b6316.png

2476d189eb3048439f7fd7558e4b18da.png

987f58fd523441aca5716bc38f95b5c1.png

生成的Bean定义们,最后自然会放入注册器中,等待实例化。


2. 实例化并注入

上面,我们说注册了个Bean定义,bean名字还叫Mapper,其实际的类已经变成了FactoryBeanFactory,如下图:

5b0a9c19f9384b68ae3f622cc6684a12.png


但是,如果各位学习过前面我们关于factoryBean的内容,就应该知道,当我们从spring容器里获取这类Bean的时候,取的并不是该Bean,而是该Bean生产出来的其他对象

  // MapperFactyoryBean.java
  @Override
  public T getObject() throws Exception {
    return getSqlSession().getMapper(this.mapperInterface);
  }

不难看出,最后是在会话中去获取一个对象,所谓会话中获取,其实最终还是要到我们上面提到的Configuration里去取,该配置对象里面有一个MapperRegistry,而从(二、1. 扫描xml文件)里,我们就提过,在扫描解析xml的时候,会向myBatisConfiguration里注册命名空间,就是存在着个位置的。此刻,就要通过这个地方,创建代理了。

7ea97743e6e84b4999ba88824630e77f.png

创建代理的详情如下,最终我们将返还一个Proxy代理对象。最终这个对象会被注入到各其他Bean里面

c505f16a266a45239ffd375f063692b5.png

我们可以看到,最终注入的确实是一个代理对象,而非所谓的mapperFactoryBean对象。


f56cb532fd9c424a8fe390874bdd2d19.png


四、流程3 —— 获取会话并执行

上面两个流程,我们其实已经做了相当多的准备,我们已经创建了 sqlSessionFactory,也把各sql解析成了MapperStatement,也在各个调用方那边注入了一个代理对象。至此三方都完成,接下来可以通过代理对象进行真正的执行了。

这里引用一张时序图:前面的步骤我们已经完成,关键在于最后的invoke

91d0223eadb0455b9d1ba66f5089ee0d.png

如果看不清,可以直接下载 mybatis sql执行时序图。

总体来说,执行可分为 获取会话->会话执行->执行器执行->statement->jdbc ,其中statement是java定义的接口,用来执行sql的,而mybatis 和 springboot 都提供了实现类。

执行器的扩展相关内容详见 Mybatis的CachingExecutor与二级缓存


需要注意的是,mybatis为用户留下了一些“”插件空间“,用户可以按规则制定一些插件,从而在上述执行的某个阶段,做出一些操作,其实现原来类似于“切面增强”,关于这部分插件,我们下次会详细说明


五、 总结

总体来说,sql执行过程分三块,


一块是mybatis自己的读取xml和配置,生成会话工厂;解析出sql内容并注册起来,并生成代理(下图左框部分 + 中间两个对象)

二是为spring服务的,暴露代理对象给spring使用(下图jdkProxy)

三是通过代理对象,拿到sqlSession会话真正执行sql (下图9、10、11步)



19e582428ab34d4da0597cabee6350eb.png

目录
相关文章
|
17小时前
|
SQL Java 数据库连接
mybatis动态sql
mybatis动态sql
|
1天前
|
JSON Java 数据格式
nbcio-boot升级springboot、mybatis-plus和JSQLParser后的LocalDateTime日期json问题
nbcio-boot升级springboot、mybatis-plus和JSQLParser后的LocalDateTime日期json问题
|
1天前
|
SQL
flowable的流程任务统计sql(续)
flowable的流程任务统计sql(续)
|
1天前
|
SQL
flowable的流程任务统计sql
flowable的流程任务统计sql
|
2天前
|
Java Spring 容器
深入理解Spring Boot启动流程及其实战应用
【5月更文挑战第9天】本文详细解析了Spring Boot启动流程的概念和关键步骤,并结合实战示例,展示了如何在实际开发中运用这些知识。
13 2
|
3天前
|
SQL Java 数据库连接
MyBatis #与$的区别以及动态SQL
MyBatis #与$的区别以及动态SQL
7 0
|
4天前
|
SQL Java 数据库连接
【mybatis】动态sql之批量增删改查
【mybatis】动态sql之批量增删改查
9 0
|
5天前
|
Java 数据库连接 Spring
Spring 整合mybatis
Spring 整合mybatis
17 2
|
5天前
|
SQL Java 数据库连接
SpringBoot整合Mybatis
SpringBoot整合Mybatis
21 2
|
9天前
|
SQL Java 数据库连接
15:MyBatis对象关系与映射结构-Java Spring
15:MyBatis对象关系与映射结构-Java Spring
29 4