@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());
    }

    

 }

 

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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • 正则提取字符串中的数字_正则表达式忽略空格python

    正则提取字符串中的数字_正则表达式忽略空格pythonpython从字符串中提取数字使用正则表达式,用法如下:##总结##^匹配字符串的开始。##$匹配字符串的结尾。##\b匹配一个单词的边界。##\d匹配任意数字。##\D匹配任意非数字字符。##x?匹配一个可选的x字符(换言之,它匹配1次或者0次x字符)。##x*匹配0次或者多次x字符。##x+匹配1次或者多次x字符。…

  • python的第三方库在哪里_第三方付款情况说明

    python的第三方库在哪里_第三方付款情况说明Python第三方库说明在哪里?0.可以跳过的介绍1.找到要第三方库0.可以跳过的介绍近期开始补习各种Python的知识,看着网上大神们python用得出神入化轻舞飞扬,虽然跟着一起安装了几十个第三方库却不会怎么用,这就尴尬了,网上找了一圈没有一个明说的,遂写此文。1.找到要第三方库Pycharm途径:1.点击File———>Setting———>搜索栏关键字pr…

  • 号称有效期至2017年的 ESET Nod32 “付费”许可证,只要能用一年就行了

    号称有效期至2017年的 ESET Nod32 “付费”许可证,只要能用一年就行了这两枚“付费”许可证流于网上已有一段时间。安装ESETNod32各版本(包括最新版ESS/EAV5)并用“二选一”激活后,ESETNod32界面显示:许可证有效期至2017-4-29;许可证类型—付费许可证。通过这段时间监测:病毒库更新正常,没有被封杀迹象。我将“付费”带引号是因为没人付费。至于能否真的坚持到2017年,依我之见大可不必纠结不必较真。安安生生无偿服务一年半载也就蛮不错了—…

  • 无名的ADRC的C语言实现

    无名的ADRC的C语言实现分为ADRC.h和ADRC.c#ifndef_ADRC_H_#define_ADRC_H_/*———————————————————————————————————————-/*本程序只供购买者学习使用,版权著作权属于无名科创团队,*无名科…

  • gif录屏与gif图片合成工具「建议收藏」

    gif录屏与gif图片合成工具「建议收藏」现在好多gif图片合成是收费的,而且可能还不太好用,这里分析的gif合成软件是个比较老的软件,但是用着还是挺好用的。还有一个录屏软件,录制保存为gif文件。百度网盘分享,无需积分:链接:https://pan.baidu.com/s/1HukTW6yJvqoUiqbzXuY5bQ提取码:pvc4欢迎关注微信公众号,分享更多实用工具:…

  • java声明数组的时候,同时赋值[通俗易懂]

    java声明数组的时候,同时赋值[通俗易懂]声明数组的时候,同时赋值int[]ary1={1,2,3};

发表回复

您的电子邮箱地址不会被公开。

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