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操作数据库实现业务逻辑了。