Mybatis源码分析 - @Mapper 怎么注入到 Spring 容器中?

394 阅读1分钟

Mybatis源码分析 - @Mapper 怎么注入到 Spring 容器中?

  1. 前言

    我们在使用spring + mybatis 的时候一般都是用 @MapperScan("包名") 的方式来实现扫描bean并注入到spring 容中。下面让我们好好扒一扒具体的实现方式。

  2. 流程大纲

    1. 通过 @MapperScan注解中引入 MapperScannerRegistrar.class 类
    2. MapperScannerRegistrar类通过实现 ImportBeanDefinitionRegistrar 接口,并重写registerBeanDefinitions方法来将MapperScannerConfigurer类注入到 spring 容器中。
    3. MapperScannerConfigurer类通过实现BeanDefinitionRegistryPostProcessor接口,重写postProcessBeanDefinitionRegistry 方法,在bean初始化之前进行一些处理。
    4. 在bean初始化之前使用 ClassPathMapperScanner 的doScan方法来实现扫描指定包名下的所有接口(默认),并添加到spring 容器中提供给后续使用。
    5. 在第4步的时候扫描到所有的接口后,接口是没有办法注入到spring容器中的,实际注入的是MapperFactoryBean类,在spring注入之前会调用checkDaoConfig()方法来验证配置同时会将Mapper接口添加到mybatis的Configuration中。
    6. 在spring注入的时候会调用MapperFactoryBean类的getObject()方法,这个方法里面就是sqlSessionTemplate.getMapper()方法了,这样就会返回一个mybatis自己动态代理生成的mapper类提供给spring容器了。
  3. 涉及知识点

    其实这里很多知识点都是spring的知识点,很多第三方组件继承spring使用的方式都同理。下面加粗的类便是需要重点阅读的类。

    1. MapperScan.class 中用到了 @Import(MapperScannerRegistrar.class)

    2. MapperScannerRegistrar.class 中实现了 ImportBeanDefinitionRegistrar

    3. MapperScannerConfigurer.class 中实现了 BeanDefinitionRegistryPostProcessor

    4. MapperScannerConfigurer.postProcessBeanDefinitionRegistry()方法中用到了 ClassPathMapperScanner

    5. 扫描Mapper文件注入 MapperFactoryBean 后,通过getObject()方法获取到mybatis代理类。