spring整合mybatis核心原理

在我常使用mybatis中,会经常使用@MapperScan注解下面我们来看看它是如何整合进到spring的,首先我们进入MapperScan会看到@Import(MapperScannerRegistrar.class)

 我们打开MapperScannerRegistrar会看到实现了ImportBeanDefinitionRegistrar接口,这个接口会在spring加载启动解析import注解的时候调用实现ImportBeanDefinitionRegistrar接口的registerBeanDefinitions方法

打开registerBeanDefinitions方法就会看到将MapperScannerConfigurer.class生成了beanefinitionBuilder

 

从上图我们可以看到,直接将MapperScannerConfigurer注册成了beanDefinitionBuilder,而MapperScannerConfigurer.class到底有什么作用呢?我们进这个类里面去看看他究竟做了什么事情

如果你对spring有了解过的话那么 BeanDefinitionRegistryPostProcessor,InitializingBean,ApplicationContextAware,BeanNameAware这几个类应该都很眼熟吧,在spring加载过程中扫描加载bean定义的时候调用实现了BeanDefinitionRegistryPostProcessor接口的postProcessBeanDefinitionRegistry方法

 新建了一个ClassPathMapperScanner类并将BeanDefinitionRegistry注册器作为构造参数传入然后调用了scan方法扫描指定包的mapper接口类,我们进入scan方法中的dosan()注意进入dosan方法要进入mybatis-spring包下面的那个方法,进入doScan方法的时候要注意,mybatis重写了ClassPathBeanDefinitionScanner的doScan方法,所以进入的应该是第二张图片的方法

 

上图中的标注1中调用父类的spring方法扫描出mapper接口的beanDefinition集合,然后再由标注2的方法进行偷天换日,将扫描出来的beanDefinition包装成factoryBean,然后在实例化bean的时候会调用factoryBean的getObject方法,在getObject方法中进行增强,也就是创建动态代理

 

 进入definition.setBeanClass(this.mapperFactoryBeanClass)代码片段的参数mapperFactoryBeanClass看一下这个工厂bean

public class MapperFactoryBean<T> extends SqlSessionDaoSupport implements FactoryBean<T> {//此类实现了factoryBean接口

  private Class<T> mapperInterface;//存放实际mapper接口的参数

  private boolean addToConfig = true;

  public MapperFactoryBean() {
    // intentionally empty
  }

  public MapperFactoryBean(Class<T> mapperInterface) {//在spring后续的getbean中将通过这个方法进行参数注入
    this.mapperInterface = mapperInterface;
  }

 下面我们找到factoryBean的getObject方法

  @Override
  public T getObject() throws Exception {
    return getSqlSession().getMapper(this.mapperInterface);//从这里跟进去就可以找到生成JDK动态代理的方法了
  }

 最终会调用到如下的代码去生成动态代理类

@Override
    public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
        // TODO 这里换成 MybatisMapperProxyFactory 而不是 MapperProxyFactory
        final MybatisMapperProxyFactory<T> mapperProxyFactory = (MybatisMapperProxyFactory<T>) knownMappers.get(type);
        if (mapperProxyFactory == null) {
            throw new BindingException("Type " + type + " is not known to the MybatisPlusMapperRegistry.");
        }
        try {
            return mapperProxyFactory.newInstance(sqlSession);//从这里进去就能看到生成动态代理的代码了,有兴趣的自己跟进去看一下就知道了
        } catch (Exception e) {
            throw new BindingException("Error getting mapper instance. Cause: " + e, e);
        }
    }

spring集成mybatis 的核心流程已经梳理完了,下面奉上一张流程图给大家参考 

 

 

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值