【Mybatis】Mapper 接口都是怎么注入到 Spring容器中的?

发布时间 2023-06-26 16:46:35作者: 酷酷-

1  前言

 这节我们看个源码相关的东西,就是我们平时写的 Mapper 接口是怎么注入到 Spring 中呢?

我们会去想:

比如Mapper接口在启动时是如何被发现的?

Mapper接口我们知道肯定是会创建代理的,那么代理对象又是如何创建的呢?

我们接下来就来看看。

2  @Mapper引发的效应

在SpringBoot与Mybatis整合的过程中,往往都会在启动类上标注 @MapperScan注解,并指定basePackage。

那我们跟进去这个注解进去瞅瞅,会发现一个 @Import ,可以看到引入的是类 MapperScannerRegistrar。

那我们进入这个类看看:

可以看到 MapperScannerRegistrar 类刚好实现的是 ImportBeanDefinitionRegistrar 接口,而@Import是spring启动执行BeanFactory后置处理器时被spring内置后置处理器ConfigurationClassPostProcessor解析,如果发现@Import引入的是一个 ImportBeanDefinitionRegistrar 的实现,则会立即调用其 registerBeanDefinitions 方法。那我们继续看:

可以看到王我们的容器里注入的一个Bean的描述文件,并且类型是 MapperScannerConfigurer,那我们来看看这个类结构:

可以看到的就是 BeanDefinitionRegistryPostProcessor ,这不是我们熟悉的一个后置处理器么,我们Debug看看:

就会执行到 MapperScannerConfigurer里的 postProcessBeanDefinitionRegistry 方法啦:

然后我们进入 Scan方法,这里要注意的是 doScan实际调用的是 mybatis-spring中的 ClassPathMapper 里的方法哈,这个很关键哈:

我们进入到doScan中来看看,对我们的BeanDefinition进行了转换,变成了MapperFactoryBean,并且设置了 SqlSessionTemplate、SqlSessionFactory等属性。

到这里我们的 Mapper接口的Bean描述文件就放进了 Spring容器了,并且Bean类型是 MapperFactoryBean包装起来的。

3  MapperFactoryBean

那我们对象怎么创建的呢,我们来看看:

通过Bean的描述文件获取Bean对象,就是执行MapperFactoryBean的getObject 方法,继而通过 SqlSession来进行代理对象的创建。

4  涉及到的关键组件

  • @MapperScan 配置扫描包并引入MapperScannerRegistrar
  • MapperScannerRegistrar 扫描Mapper接口以及增强MapperFactoryBean创建代理对象的埋入
  • ImportBeanDefinitionRegistrar Bean描述文件放进Spring容器
  • ClassPathBeanDefinitionScanner ClassPathMapperScanner 扫描增强

5  小结

好啦,本节我们主要看了一下 Mapper接口是怎么和 Spring融合的哈,有理解不对的地方欢迎指正哈。