Mybatis整合SpringBoot自动扫描Mapper接口类注册Bean

首先引入官方提供的mybaits和SpringBoot整合的依赖包:

xml 复制代码
<dependency>
  <groupId>org.mybatis.spring.boot</groupId>
  <artifactId>mybatis-spring-boot-starter</artifactId>
  <version>2.3.1</version>
</dependency>

该依赖包中提供了两种扫描方式(当然也可能存在更多的方式只是我没有发现,如果有了解的朋友希望可以在评论中补充一下)。

自动装配

首先就是SpringBoot的自动装配方式,SpringBoot自动装配原理就不再过多讲述了,咱们直接说mybaits相关的内容。 Mybatis提供了自动装配类 org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration, 在MybatisAutoConfiguration类中有一个静态内部类:

java 复制代码
@org.springframework.context.annotation.Configuration
@Import(AutoConfiguredMapperScannerRegistrar.class)
@ConditionalOnMissingBean({ MapperFactoryBean.class, MapperScannerConfigurer.class })
public static class MapperScannerRegistrarNotFoundConfiguration implements InitializingBean {

  @Override
  public void afterPropertiesSet() {
    logger.debug(
        "Not found configuration for registering mapper bean using @MapperScan, MapperFactoryBean and MapperScannerConfigurer.");
  }

}

本次的重点是 @Import(AutoConfiguredMapperScannerRegistrar.class)这一行,使用Spring的@Import注解向容器中添加了一个AutoConfiguredMapperScannerRegistrar类型的Bean;

AutoConfiguredMapperScannerRegistrar类实现了ImportBeanDefinitionRegistrar接口,生成Bean的时候会回调该接口中的registerBeanDefinitions()方法;

在该方法中向Spring容器中放入了一个MapperScannerConfigurer类型的Bean,并设置了一些属性值:

MapperScannerConfigurer实现了BeanDefinitionRegistryPostProcessor接口,在创建Bean的时候会回调其postProcessBeanDefinitionRegistry()方法; 该方法中通过使用ClassPathMapperScanner扫描类,并过滤需要的类然后加载成BeanDefinition,然后通过BeanDefinition创建SpringBean。

ClassPathMapperScannerClassPathScanningCandidateComponentProvider的子类,ClassPathScanningCandidateComponentProvider是SpringBoot提供的一个工具,可以扫描指定包下符合要求的类,并加载成BeanDefinition

如上图所示,我们重点需要关注的一共有三行:

  • scanner.setMapperFactoryBeanClass():设置FactoryBean,用来生成SpringBean,比如大家都知道Mybatis是依靠动态代理实现的,创建代理类的逻辑入口就在这个类里面。
  • scanner.registerFilters():设置过滤器,用来过滤感兴趣的类,比如Mybatis会扫描所有添加了@Mapper注解的接口,其逻辑就是在这个方法中设置的
  • scanner.scan():具体的处理逻辑

我们重点就说一下第三个方法。 scan()方法内部调用了doScan()方法,doScan()是重写的父类的方法,不过可以从下图中看到,最终的扫描处理还是交给父类进行的,Mybatis主要是添加了一个processBeanDefinitions()方法。

这个方法中的重点就是下面这一行,是不是很熟悉,没错,就是刚刚说的第一条,将FactoryBean设置进BeanDefinition,生成最终的Bean对象的时候会调用FactoryBean的getObject()方法。

MapperScan

java 复制代码
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(MapperScannerRegistrar.class)
@Repeatable(MapperScans.class)
public @interface MapperScan {}

从上面的代码中可以看到,依旧是使用@Import注解注入了一个MapperScannerRegistrar类型的Bean,同样会调用他的registerBeanDefinitions()方法;

在该方法中会创建一个MapperScannerConfigurer类型的BeanDefinition,然后添加到Spring容器中,看到这是不是很熟悉了,没错,就是上面的逻辑,不再多说,从上面再看一遍就行了。

相关推荐
雨过天晴而后无语12 分钟前
Windchill10+html使用Lightbox轻量化wizard的配置
java·前端·html
Yeniden28 分钟前
设计模式>原型模式大白话讲解:就像复印机,拿个原件一复印,就得到一模一样的新东西
java·设计模式·原型模式·1024程序员节
披着羊皮不是狼44 分钟前
HTTP 与 API 入门:理解前后端交互原理
java·网络协议·http·交互
2401_841495641 小时前
【操作系统】模拟真实操作系统核心功能的Java实现
java·操作系统·进程管理·系统调用·并发控制·中断处理·cpu调度
程序员皮皮林1 小时前
Java 25 正式发布:更简洁、更高效、更现代!
java·开发语言·python
好家伙VCC1 小时前
**发散创新:AI绘画编程探索与实践**随着人工智能技术的飞速发展,AI绘
java·人工智能·python·ai作画
勇者无畏4041 小时前
基于 Spring AI Alibaba 搭建 Text-To-SQL 智能系统(前置介绍)
java·后端·spring·prompt·embedding
练习时长一年1 小时前
IDEA开发常用快捷键总结
java·ide·intellij-idea
温柔53291 小时前
仓颉语言异常捕获机制深度解析
java·服务器·前端
运维李哥不背锅2 小时前
Ansible 的变量与模板:实现更灵活的自动化配置
java·自动化·ansible