@MapperScan扫描

@MapperScan扫描@MapperScan@MapperScan({“com.kq.mybatis.mapper”,”com.kq.mybatis1.mapper”})publicvoidregisterBeanDefinitions(AnnotationMetadataimportingClassMetadata,BeanDefinitionRegistryregistry){AnnotationAttributesmapperScanAttrs=AnnotationAttribute

大家好,又见面了,我是你们的朋友全栈君。

@MapperScan

@MapperScan({"com.kq.mybatis.mapper","com.kq.mybatis1.mapper"})
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
    AnnotationAttributes mapperScanAttrs = AnnotationAttributes
        .fromMap(importingClassMetadata.getAnnotationAttributes(MapperScan.class.getName()));
    if (mapperScanAttrs != null) {
      registerBeanDefinitions(mapperScanAttrs, registry, generateBaseBeanName(importingClassMetadata, 0));
    }
  }

 

这样是默认扫描com.kq.mybatis.mapper和com.kq.mybatis1.mapper包下的所有.clsss文件,而不是扫描这2个包下的所有Mapper文件

@MapperScan扫描

@MapperScan指定markerInterface

这里通过@MapperScan指定markerInterface,这样扫描出来的都是实现该接口的Mapper

@MapperScan(value = {"com.kq.scan.mybatis.mapper","com.kq.scan.mybatis1.mapper"},markerInterface = MybatisBaseMapper.class)


public interface AccountMapper extends MybatisBaseMapper {  }

这个markerInterface 最终设置的是MapperScannerConfigurer的 markerInterface属性

@MapperScan指定annotationClass


@MapperScan(value = {"com.kq.scan.mybatis.mapper","com.kq.scan.mybatis1.mapper"},markerInterface = MybatisBaseMapper.class,annotationClass=Mapper.class)


@Mapper
public interface UserMapper { }

这个annotationClass最终设置的是MapperScannerConfigurer的 annotationClass属性

注意:

@MapperScan同时指定markerInterface 和 annotationClass 两个元素的时候,只要1个条件满足,就算符合条件,而不是要两个条件都满足

 

MapperScannerRegistrar

BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(MapperScannerConfigurer.class);
    builder.addPropertyValue("processPropertyPlaceHolders", true);

    Class<? extends Annotation> annotationClass = annoAttrs.getClass("annotationClass");
    if (!Annotation.class.equals(annotationClass)) {
      builder.addPropertyValue("annotationClass", annotationClass);
    }

    // 看这里 markerInterface
    Class<?> markerInterface = annoAttrs.getClass("markerInterface");
    if (!Class.class.equals(markerInterface)) {
      builder.addPropertyValue("markerInterface", markerInterface);
}

 

@MapperScans

@MapperScans({@MapperScan("com.kq.mybatis.mapper"),@MapperScan("com.kq.mybatis1.mapper")})
static class RepeatingRegistrar extends MapperScannerRegistrar {
   
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
      AnnotationAttributes mapperScansAttrs = AnnotationAttributes
          .fromMap(importingClassMetadata.getAnnotationAttributes(MapperScans.class.getName()));
      if (mapperScansAttrs != null) {
        AnnotationAttributes[] annotations = mapperScansAttrs.getAnnotationArray("value");
        for (int i = 0; i < annotations.length; i++) {
          registerBeanDefinitions(annotations[i], registry, generateBaseBeanName(importingClassMetadata, i));
        }
      }
    }
  }

@MapperScan扫描

使用@MapperScans,spring的bean定义,注册的MapperScannerRegistrar 有多个的,看上图

 

注意

每个@MapperScan最终都会初始化1个MapperScannerConfigurer,主要关键的属性basePackage、annotationClass、markerInterface

 

主要相关类

org.mybatis.spring.annotation.MapperScannerRegistrar
org.mybatis.spring.mapper.MapperScannerConfigurer

类图

@MapperScan扫描

@MapperScan扫描

 

总结

@MapperScan主要就是扫描得到mybatis的Mapper,并最终在Spring容器种初始化

 

未配置@MapperScan

org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration
/**
   * If mapper registering configuration or mapper scanning configuration not present, this configuration allow to scan
   * mappers based on the same component-scanning path as Spring Boot itself.
   */
  @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.");
    }

  }

重点看下面这句话

If mapper registering configuration or mapper scanning configuration not present, this configuration allow to scan
    mappers based on the same component-scanning path as Spring Boot itself.

(如果不存在mapper注册配置或mapper扫描配置,则此配置允许扫描mapper基于与Spring Boot本身相同的组件扫描路径。)

 

AutoConfiguredMapperScannerRegistrar 

org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration

public static class AutoConfiguredMapperScannerRegistrar implements BeanFactoryAware, ImportBeanDefinitionRegistrar {

    private BeanFactory beanFactory;

    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

      if (!AutoConfigurationPackages.has(this.beanFactory)) {
        logger.debug("Could not determine auto-configuration package, automatic mapper scanning disabled.");
        return;
      }

      logger.debug("Searching for mappers annotated with @Mapper");

      List<String> packages = AutoConfigurationPackages.get(this.beanFactory);
      if (logger.isDebugEnabled()) {
        packages.forEach(pkg -> logger.debug("Using auto-configuration base package '{}'", pkg));
      }

      BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(MapperScannerConfigurer.class);
      builder.addPropertyValue("processPropertyPlaceHolders", true);
      builder.addPropertyValue("annotationClass", Mapper.class); //指定扫描的注解
      builder.addPropertyValue("basePackage", StringUtils.collectionToCommaDelimitedString(packages)); //和springboot一致
      BeanWrapper beanWrapper = new BeanWrapperImpl(MapperScannerConfigurer.class);
      Stream.of(beanWrapper.getPropertyDescriptors())
          // Need to mybatis-spring 2.0.2+
          .filter(x -> x.getName().equals("lazyInitialization")).findAny()
          .ifPresent(x -> builder.addPropertyValue("lazyInitialization", "${mybatis.lazy-initialization:false}"));
      registry.registerBeanDefinition(MapperScannerConfigurer.class.getName(), builder.getBeanDefinition());
    }

    

 }

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/137423.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • kfold_机器学习gridsearchcv(网格搜索)和kfold validation(k折验证)

    kfold_机器学习gridsearchcv(网格搜索)和kfold validation(k折验证)网格搜索算法是一种通过遍历给定的参数组合来优化模型表现的方法。以决策树为例,当我们确定了要使用决策树算法的时候,为了能够更好地拟合和预测,我们需要调整它的参数。在决策树算法中,我们通常选择的参数是决策树的最大深度。于是我们会给出一系列的最大深度的值,比如{‘max_depth’:[1,2,3,4,5]},我们会尽可能包含最优最大深度。不过,我们如何知道哪一个最大深度的模型是最好的呢?我们需要一…

    2022年9月19日
  • 原来jdk自带了这么好玩的工具 > JPS使用教程「建议收藏」

    原来jdk自带了这么好玩的工具 > JPS使用教程「建议收藏」jps(JavaVirtualMachineProcessStatusTool)jsp是java提供的一个显示当前所有java进程pid的命令,适合在linux/unix平台上简单察看当前java进程的一些简单情况。很多人都是用过unix系统里的ps命令,这个命令主要是用来显示当前系统的进程情况,有哪些进程以及进程id。jps也是一样,它的作用是显示当前系统的java进程情况及进程id。我们可以通过它来查看我们到底启动了几个java进程(因为每一个java程序都会独占一个java虚拟机实

    2022年9月20日
  • 【幻灯片分享】揭开IPA文件的灰沙 — 通过静态分析工具了解IPA实现 | 友盟 张超 | iOS DevCamp

    【幻灯片分享】揭开IPA文件的灰沙 — 通过静态分析工具了解IPA实现 | 友盟 张超 | iOS DevCamp

    2021年5月11日
  • document.all的详细解释(document.all基本上所有浏览器可用!)

    document.all的详细解释(document.all基本上所有浏览器可用!)从何而来从IE4开始IE的objectmodel才增加了document.all对象,MSDN中也对Object.all有详细的说明,Object.all是个HTMLCollection,不是数组,它包含document.all:http://msdn.microsoft.com/en-us/library/ms537434%28VS.85%29.aspx自他出现后,IE后续版本也…

    2022年7月12日
  • C语言括号匹配(栈括号匹配c语言)

    给定一串字符,不超过100个字符,可能包括括号、数字、字母、标点符号、空格,编程检查这一串字符中的(),[],{}是否匹配。输入格式:输入在一行中给出一行字符串,不超过100个字符,可能包括括号、数字、字母、标点符号、空格。输出格式:如果括号配对,输出yes,否则输出no。输入样例1:sin(10+20)输出样例1:yes输入样例2:{[}]输出样例2:no思路:题目输入一些字符串,我们就先保留括号之类的,判断是否匹配。如果遇到左括号,就入栈,如果遇到一个右括号,就与栈顶元

    2022年4月13日
  • Godaddy域名与空间解析教程(全)「建议收藏」

    Godaddy域名与空间解析教程(全)「建议收藏」最近忙着开自己的独立博客,既然以后是打算从事外贸相关的电子商务,我打算从Godaddy下手学习外贸空间的选择。1.购买Godaddy,为什么选狗爹,便宜、稳定、再加上可以用支付宝,省去代购的繁琐。这

    2022年8月5日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号