• Mybatis的原理分析1(@Mapper是如何生效的)


      接着我们上次说的SpringBoot自动加载原理。我们大概明白了在maven中引入mybatis后,这个模块是如下加载的。

      可能会有人问了,一般我们的dao层都是通过Mapper接口+Mapper.xml的方式来操作数据库的,但是@Mapper注解并不是SpringBoot自带的注解,为什么加上@Mapper注解后这个接口就能够在项目中被各处注入使用了呢?

      1:我们在maven中引入mybatis后就会自动加载 MybatisAutoConfiguration 这个类,它包含一个内部类 AutoConfiguredMapperScannerRegistrar,我们可以查看这个类的源码,部分如下:

     1   public static class AutoConfiguredMapperScannerRegistrar
     2       implements BeanFactoryAware, ImportBeanDefinitionRegistrar, ResourceLoaderAware {
     3 
     4     private BeanFactory beanFactory;
     5 
     6     private ResourceLoader resourceLoader;
     7 
     8     @Override
     9     public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
    10 
    11       logger.debug("Searching for mappers annotated with @Mapper");
    12 
    13       ClassPathMapperScanner scanner = new ClassPathMapperScanner(registry);
    14 
    15       try {
    16         if (this.resourceLoader != null) {
    17           scanner.setResourceLoader(this.resourceLoader);
    18         }
    19 
    20         List<String> packages = AutoConfigurationPackages.get(this.beanFactory);
    21         if (logger.isDebugEnabled()) {
    22           for (String pkg : packages) {
    23             logger.debug("Using auto-configuration base package '{}'", pkg);
    24           }
    25         }
    26 
    27         scanner.setAnnotationClass(Mapper.class);
    28         scanner.registerFilters();
    29         scanner.doScan(StringUtils.toStringArray(packages));
    30       } catch (IllegalStateException ex) {
    31         logger.debug("Could not determine auto-configuration package, automatic mapper scanning disabled.", ex);
    32       }
    33     }

      我们会看到有个 registerBeanDefinitions() 方法。没错,这个方法就是那些被@Mapper标记的接口能被注入到SpringBoot的BeanFactory的关键。我们阅读这个方法,会发现有个 scanner.doScan(StringUtils.toStringArray(packages)),它是干嘛的,我们跳进去看一下,部分代码如下:

     1   @Override
     2   public Set<BeanDefinitionHolder> doScan(String... basePackages) {
     3     Set<BeanDefinitionHolder> beanDefinitions = super.doScan(basePackages);
     4 
     5     if (beanDefinitions.isEmpty()) {
     6       logger.warn("No MyBatis mapper was found in '" + Arrays.toString(basePackages) + "' package. Please check your configuration.");
     7     } else {
     8       processBeanDefinitions(beanDefinitions);
     9     }
    10 
    11     return beanDefinitions;
    12   }

      这个doScan方法调用了父类ClassPathBeanDefinitionScanner的doScan方法。这个类是Bean被注入BeanFactory的关键类,doScan方法是其中的关键方法,这里就不再分析。

      那么通过这块,我们得到了哪些呢?

      1:@Mapper注解的类是如何被注入到ApplicationContext(或者BeanFactory)里的

  • 相关阅读:
    Python中常用的模块(sys模块)
    Python中常用的模块(OS模块)
    Python中常用的模块(time模块)
    Python中常用的模块(random模块)
    Python生成器详解
    Python装饰器详解
    python 两个list 求交集,并集,差集
    数据库中的视图索引
    数据库中的外键和主键理解
    mssql学习
  • 原文地址:https://www.cnblogs.com/wanghaoyang/p/11224298.html
Copyright © 2020-2023  润新知