springboot与mybatis-plus集成原理

前面的文章已经介绍,与springboot集成的最好方式是使用自动配置,也就是实现自己的starter,比如本文介绍的mybatisplus-spring-boot-starter

获取自动配置类

# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration

  该类有一个静态内部类

@Configuration
    @Import({AutoConfiguredMapperScannerRegistrar.class})
    @ConditionalOnMissingBean(MapperFactoryBean.class)
    public static class MapperScannerRegistrarNotFoundConfiguration implements InitializingBean {

        @Override
        public void afterPropertiesSet() {
            logger.debug("No {} found.", MapperFactoryBean.class.getName());
        }
    }

  这里的AutoConfiguredMapperScannerRegistrar实现了ImportBeanDefinitionRegistrar接口,它就是spring扩展的一个重要入口,为了加深理解,咱们先说下它的作用:目的是我们自己构建bd注册到bd map中,这里的bd其实就是class的包装对象,也是生成spring对象的重要来源。

com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration.AutoConfiguredMapperScannerRegistrar#registerBeanDefinitions

  这个方法通过ClassPathMapperScanner扫描Mapper注解,其实就是mybatis定义的mapper接口,每一个mapper接口对应一个bd

org.mybatis.spring.mapper.ClassPathMapperScanner#processBeanDefinitions

  该方法对bd进行偷梁换柱,将beanclass设置为mapperFactoryBean,利用它才能生成mapper代理对象

definition.setBeanClass(this.mapperFactoryBean.getClass());

  另外,将MapperFactoryBean构造方法的参数,也即mapperInterface设置为mapper接口,这里的目的其实就是实现mapperFactoryBean动态获取mapper代理对象的能力

definition.getConstructorArgumentValues().addGenericArgumentValue(beanClassName);
public MapperFactoryBean(Class<T> mapperInterface) {
    this.mapperInterface = mapperInterface;
  }

  mapper代理对象的获取如下:

  public T getObject() throws Exception {
    return getSqlSession().getMapper(this.mapperInterface);
  }
    protected T newInstance(MapperProxy<T> mapperProxy) {
        return Proxy.newProxyInstance(this.mapperInterface.getClassLoader(), new Class[]{this.mapperInterface}, mapperProxy);
    }

  这里的getSqlSession()方法,其实就是获取sqlSessionTemplate对象,而实例化MapperFactoryBean对象时,依赖sqlSessionTemplate,所以就执行一开始的

MybatisPlusAutoConfiguration中的方法,SqlSessionFactory 也同理

@Bean
    @ConditionalOnMissingBean
    public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
        ExecutorType executorType = this.properties.getExecutorType();
        if (executorType != null) {
            return new SqlSessionTemplate(sqlSessionFactory, executorType);
        } else {
            return new SqlSessionTemplate(sqlSessionFactory);
        }
    }

       至此,我们已经知道可以获取到spring管理的mapper代理对象了,在service层时,也就可以利用mapper操作数据库实现业务逻辑了。

 

posted @ 2022-01-31 23:35  abingtech  阅读(490)  评论(0编辑  收藏  举报