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

目录
相关文章
|
1天前
|
SQL Java 数据库连接
【极光系列】SpringBoot集成Mybatis
【极光系列】SpringBoot集成Mybatis
10 1
【极光系列】SpringBoot集成Mybatis
|
1天前
|
XML 监控 druid
【Java专题_02】springboot+mybatis+pagehelper分页插件+druid数据源详细教程
【Java专题_02】springboot+mybatis+pagehelper分页插件+druid数据源详细教程
5 0
|
1天前
|
存储 SQL 数据安全/隐私保护
Mybatis-Plus 拦截SQL语句实现加解密存储
Mybatis-Plus 拦截SQL语句实现加解密存储
5 0
|
19天前
|
缓存 Java uml
SpringBoot2 | Spring IOC 流程中核心扩展接口的12个扩展点源码分析(十一)
SpringBoot2 | Spring IOC 流程中核心扩展接口的12个扩展点源码分析(十一)
22 0
|
19天前
|
Java 容器 Spring
SpringBoot2 | @SpringBootApplication注解 自动化配置流程源码分析(三)
SpringBoot2 | @SpringBootApplication注解 自动化配置流程源码分析(三)
22 0
|
19天前
|
设计模式 Java 容器
SpringBoot2 | SpringBoot启动流程源码分析(二)
SpringBoot2 | SpringBoot启动流程源码分析(二)
21 0
|
19天前
|
Java 中间件 容器
SpringBoot2 | SpringBoot启动流程源码分析(一)
SpringBoot2 | SpringBoot启动流程源码分析(一)
24 0
|
20天前
|
SQL 缓存 Java
JAVAEE框架技术之8-myBatis ORM框架技术参数和动态SQL语句
JAVAEE框架技术之8-myBatis ORM框架技术参数和动态SQL语句
58 0
JAVAEE框架技术之8-myBatis ORM框架技术参数和动态SQL语句
|
22天前
|
SQL Oracle 关系型数据库
整合Mybatis-Plus高级,Oracle 主键Sequence,Sql 注入器实现自定义全局操作
整合Mybatis-Plus高级,Oracle 主键Sequence,Sql 注入器实现自定义全局操作
74 0
|
22天前
|
SQL XML Java
【MyBatis】动态SQL
【MyBatis】动态SQL

相关产品

  • 云迁移中心