一、整合步骤

mybatis-spring-1.3.2版本

  1. 使用@MapperScan注解,配置Mapper路径
    1. @MapperScan继承@Import注解。
    2. @Import引入MapperScannerRegistrar(是ImportBeanDefinitionRegistrar实现类)(Spring会在解析配置类逻辑中,解析Import、MapperScan注解)
  2. 利用ImportBeanDefinitionRegistrar(Spring扩展机制)。完成Mapper接口的扫描(继承并重写Spring扫描器)、修改与注册Mapper的BeanDefinition。【2.0.6或更高版本中,MapperScannerRegistrar注册实现BeanDefinitionRegistryPostProcessor的MapperScannerConfigurer完成扫描、修改BeanDefinition的动作】
    1. Spring容器会调用ImportBeanDefinitionRegistrar#registerBeanDefinitions
    2. 获取MapperScan注解实例
    3. 实例化自定义的扫描器(ClassPathMapperScanner),并利用MapperScan注解实例,将配置参数【重点参数:Mapper包路径】设置到扫描器中
    4. 向自定义扫描器中,注册自定义扫描过滤器(总是返回true,即不进行过滤)。Spring默认过滤器,仅扫描被@Component注解标记的类
    5. 执行扫描方法(doScan),(扫描@MapperScan注解配置的路径下的Mapper接口),得到Mapper接口的BeanDefinitionHolder集合。
    6. 循环BeanDefinitionHolder集合,修改BeanDefinition实例属性。
      1. 设置ConstructorArgumentValues属性值:原始的BeanClass。即:xxMapper的Class对象。(构造函数入参)
      2. 修改BeanClass属性为:MapperFactoryBean的Class对象,
      3. 设置AutowireMode属性为:2(byType方式注入)。
    7. 经过上一步,所有Mapper接口的BeanDefinition,都变成FactoryBean类型的
  3. 利用FactoryBean将Mapper接口的代理对象,注册为Spring容器的实例对象。
    1. 每个mapper接口,都对应一个MapperFactory类型的Bean的BeanDefinition
    2. MapperFactoryBean的getObject方法,首先获得sqlSession对象,然后根据步骤2.f.i中构造函数传递的Class参数,获取对应Mapper 的代理对象。并将代理对象缓存到Spring容器中。
    3. 利用Spring的依赖注入功能。完成Mybatis代理对象的依赖注入
  4. 因为MapperFactoryBean的AutowireMode是byType,所以Spring会调用set方法(setSqlSessionFactory(SqlSessionFactory sqlSessionFactory)、setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate))
    1. SqlSessionFactory需要开发者自行实例化,提供给Spring,Spring才能顺利调用上面set方法
    2. SqlSessionFactory会被包装成SqlSessionTemplate(SqlSessionTemplate实现了SqlSession接口)

二、整合源码分析

image.png
image.png