@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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 什么叫侧面指纹识别_新科技?侧面指纹解锁有什么不同?

    什么叫侧面指纹识别_新科技?侧面指纹解锁有什么不同?原标题:新科技?侧面指纹解锁有什么不同?手机的时代更新的太快,以前诺基亚的密码解锁,到后来安卓苹果的指纹解锁,虹膜解锁,面部识别解锁,各式各样的解锁方式。不过今天说的主题也是指纹解锁,不过不是以往的正面home键,也不是背面指纹解锁器,而是侧面指纹解锁。不得不承认,智能交互时代不断刷新人们的生活,智能手机行业也发展得如火如荼。各智能手机厂商凭借在手机里边加入各种“黑科技”,用自己独特的风格来吸引消…

    2022年6月15日
    62
  • Web应用的UML建模与.NET框架开发

    Web应用的UML建模与.NET框架开发

    2022年3月12日
    338
  • 深入理解java中的自动装箱与拆箱[通俗易懂]

    本文由java语言入门栏目为大家推荐,文中通过详细实例为大家深入讲解了java中的自动装箱与拆箱的相关知识,希望可以帮助到大家。装箱是把基本数据类型转换为包装类,拆箱是把包装类转换为基本数据类型。

    2022年1月17日
    41
  • 罗马字符及其发音_五十音发音

    罗马字符及其发音_五十音发音
    小写大写中文音英文音标
    αΑ阿尔法aerfar
    βΒ卑塔beita
    γΓ嘎吗gama
    δΔ德儿塔derlta
    εΕ依普西龙ipuseilong
    ζΖzei塔zeita
    ηΗ衣塔ita
    θΘsi塔sital
    ιΙ哟塔yota
    κΚ卡怕kapa
    λ∧拉姆达lamonda
    μΜ谬mju

    2022年9月30日
    0
  • pycharm代码运行不显示结果_pycharm运行配置错误

    pycharm代码运行不显示结果_pycharm运行配置错误我最近看了两节关于数据分析的课程,其中最基础也最重要的知识就是支持度,置信度和提升度了。而在打印提升度的相关信息时,我遇到了一些麻烦!老师用的是JupyterNotebook来演示,而我用的是pycharm(其实跟编译器没关系),然后打印提升度时我发现有很多数据我无法打印出来!只是给我留了半串省略号…我就纳闷了,到底是啥原因?shopping_basket={‘ID’:[1,2,3,4,5,6],’Basket’:[[‘Onion’,’Bee

    2022年8月29日
    1
  • 【windows屏幕扩展】把你多余屏幕利用起来,spacedesk屏幕扩展超低延迟解决方案[通俗易懂]

    【windows屏幕扩展】把你多余屏幕利用起来,spacedesk屏幕扩展超低延迟解决方案[通俗易懂]目录扫盲扫盲spacedesk是一款基于TCP/IP协议的屏幕扩展工具,通过这款工具你可以把自己身边的闲置的平板手机或者笔记本利用起来,扩展你的屏幕。只要你的两台设备处于同一个网络环境下(只要互相能够ping通),你就可以实现屏幕扩展(卡不卡我就不知道了)。用过win10中的wifi扩展屏幕的同学都知道,扩展的屏幕显示质量和网络环境成正比。而win10的屏幕扩展很玄学,…

    2022年8月13日
    3

发表回复

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

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