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)里的

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM