从源码看世界:Springboot整合Mybatis后到底做了什么

Mybatis一次数据库操作过程 的文章中,我展示了使用Mybatis操作数据库的demo,但实际使用时并不会这里写代码,因为一般都会使用springboot了,那现在我们一起来看看Springboot整合Mybatis之后到底为我们做了哪些事情。

要在Springboot整合Mybatis,首先修改pom依赖:

<!--<dependency>
	<groupId>org.mybatis</groupId>
	<artifactId>mybatis</artifactId>
	<version>3.5.3</version>
</dependency>-->

<dependency>
	<groupId>org.mybatis.spring.boot</groupId>
	<artifactId>mybatis-spring-boot-starter</artifactId>
	<version>2.1.1</version>
</dependency>

然后在具体的mapper类中增加 @Repository ,让spring管理其实例;接着在Application增加@MapperScan("mapper所在的包路径")。

现在,只要在需要使用mapper的地方使用@Autowired自动注入即可使用:

@Autowired
private StudentMapper studentMapper;

@GetMapping("/test")
public String test() {
	Student student = studentMapper.getById(1);
	return student.getName();
}

至此,Springboot已经成功整合Mybatis,使用起来的确十分方便。但Mybatis的步骤肯定没有减少,只不过spring帮我们做了而已,那它到底在哪里自动完成的呢?

从引入的依赖命名来看,这个是mybatis开箱即用的starter(具体原理请查阅springboot的starter原理,此处不再赘述),因此首先查看spring.factory指定了哪些自动配置类:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.mybatis.spring.boot.autoconfigure.MybatisLanguageDriverAutoConfiguration,\
org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration

第一个是动态语言驱动,主要看MybatisAutoConfiguration:里面注册了两个实例SqlSessionFactory与SqlSessionTemplate。注意,它们同时用了@ConditionalOnMissingBean注解,即没有这个bean的时候才生效,例如我们自己注册了SqlSessionFactory,因此MybatisAutoConfiguration的就不再实例化了。而SqlSessionTemplate是SqlSession的实现类,可以推测spring使用这个代替mybatis的DefaultSqlSession。

既然SqlSessionFactory和SqlSession都有了,那两者是如何关联起来的呢?

还记得上面我们用了@MapperScan来指定mapper所在的包路径吧,因此可以在这个注解作为入口,里面最重要的是@Import(MapperScannerRegistrar.class),而MapperScannerRegistrar实现了ImportBeanDefinitionRegistrar,得到BeanDefinitionRegistry对象,然后根据@MapperScan的配置注册了beanClass=MapperScannerConfigurer的BeanDefinition。

  void registerBeanDefinitions(AnnotationAttributes annoAttrs, BeanDefinitionRegistry registry, String beanName) {

    BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(MapperScannerConfigurer.class);
    // ...
    registry.registerBeanDefinition(beanName, builder.getBeanDefinition());
}

再来看看MapperScannerConfigurer,它实现了BeanDefinitionRegistryPostProcessor,也能得到BeanDefinitionRegistry对象,然后创建了ClassPathMapperScanner对象,从命名上看可以推测是扫描mapper用的,它继承了ClassPathBeanDefinitionScanner,同时重写了doScan方法:

  @Override
  public Set<BeanDefinitionHolder> doScan(String... basePackages) {
    Set<BeanDefinitionHolder> beanDefinitions = super.doScan(basePackages);

    if (beanDefinitions.isEmpty()) {
      LOGGER.warn(() -> "No MyBatis mapper was found in '" + Arrays.toString(basePackages)
          + "' package. Please check your configuration.");
    } else {
      processBeanDefinitions(beanDefinitions);
    }

    return beanDefinitions;
  }

一旦扫描到需要实例化的侯选对象,就会进入processBeanDefinitions方法。这里细心的同学可能会问,到底哪些侯选对象对符合条件呢?ClassPathMapperScanner还重写了isCandidateComponent方法:

  @Override
  protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
    return beanDefinition.getMetadata().isInterface() && beanDefinition.getMetadata().isIndependent();
  }

即既是接口又是独立类才符合条件。

在processBeanDefinitions最重要的作用是将侯选对象的beanClass改为MapperFactoryBean,从命名也可以推测是实例化Mapper的代理工厂,而它确实实现了FactoryBean,当mapper真正需要实例化的时候,就会调用MapperFactoryBean的getObject方法:

  @Override
  public T getObject() throws Exception {
    return getSqlSession().getMapper(this.mapperInterface);
  }

而getSqlSession()获得的正是SqlSessionTemplate,至此SqlSessionFactory和SqlSession就关联起来了。

最后,可能还有同学会问:难道既是接口又是独立类就作为mapper来处理了吗,不会代理错了吗?这个其实无需担心,因为MapperProxy会做判断,条件不足时会抛出异常,因此实例化自然就失败了

为了在Windows安装ADB工具,你可以按照以下步骤进行操作: 1. 首先,下载ADB工具包并解压缩到你自定义的安装目录。你可以选择将其解压缩到任何你喜欢的位置。 2. 打开运行窗口,可以通过按下Win+R键来快速打开。在运行窗口中输入"sysdm.cpl"并按下回车键。 3. 在系统属性窗口中,选择"高级"选项卡,然后点击"环境变量"按钮。 4. 在环境变量窗口中,选择"系统变量"部分,并找到名为"Path"的变量。点击"编辑"按钮。 5. 在编辑环境变量窗口中,点击"新建"按钮,并将ADB工具的安装路径添加到新建的路径中。确保路径正确无误后,点击"确定"按钮。 6. 返回到桌面,打开命令提示符窗口。你可以通过按下Win+R键,然后输入"cmd"并按下回车键来快速打开命令提示符窗口。 7. 在命令提示符窗口中,输入"adb version"命令来验证ADB工具是否成功安装。如果显示版本信息,则表示安装成功。 这样,你就成功在Windows安装ADB工具。你可以使用ADB工具来执行各种操作,如枚举设备、进入/退出ADB终端、文件传输、运行命令、查看系统日志等。具体的操作方法可以参考ADB工具的官方文档或其他相关教程。\[1\]\[2\]\[3\] #### 引用[.reference_title] - *1* [windows环境安装adb驱动](https://blog.youkuaiyun.com/zx54633089/article/details/128533343)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [Windows安装使用ADB简单易懂教程](https://blog.youkuaiyun.com/m0_37777700/article/details/129836351)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值