【一】MyBatis-Spring最全源码详解之@MapperScan到底在弄啥

目录1. invokeBeanFactoryPostProcessors2. MapperScannerRegistrar#registerBeanDefinitions3. ClassPathMapperScanner#processBeanDefinitions4. 附录:项目文档在Springboot项目中使用MyBatis往往会使用@MapperScan("packag...
摘要由CSDN通过智能技术生成

目录

1. invokeBeanFactoryPostProcessors

2. MapperScannerRegistrar#registerBeanDefinitions

3. ClassPathMapperScanner#processBeanDefinitions

4. 附录:项目文档


在Springboot项目中使用MyBatis往往会使用@MapperScan("package")注解。那么这个注解有什么用呢?本篇文章就从源码层面来分析该注解到底在弄啥。

点开@MapperScan注解会发现有一个@Import(MapperScannerRegistrar.class)注解。记住MapperScannerRegistrar.class这个类,待会儿会有用。

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(MapperScannerRegistrar.class)
public @interface MapperScan

1. invokeBeanFactoryPostProcessors

让我们回顾Sping容器的启动流程。

public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        prepareRefresh();
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
        prepareBeanFactory(beanFactory);

        try {
            postProcessBeanFactory(beanFactory);
            invokeBeanFactoryPostProcessors(beanFactory);
            registerBeanPostProcessors(beanFactory);
            initMessageSource();
            initApplicationEventMulticaster();
            onRefresh();
            registerListeners();
            finishBeanFactoryInitialization(beanFactory);
            finishRefresh();
        }
        finally {            
            resetCommonCaches();
        }
    }
}

在refresh方法中(对应Springboot项目的org.springframework.boot.SpringApplication#refreshContext中的refresh方法)。invokeBeanFactoryPostProcessors方法《【四】Spring IoC 最全源码详解之 invokeBeanFactoryPostProcessors与ConfigurationClassPostProcessor扫包》一文中已经介绍了ConfigurationClassPostProcessor#processConfigBeanDefinitions方法中的parser.parse(candidates)方法(如果读者不懂该步骤的作用和流程,强烈建议读者不要再往下读了。因为后面的你根本读不懂!)。

do {
    parser.parse(candidates);
    parser.validate();

    Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
    configClasses.removeAll(alreadyParsed);

    if (this.reader == null) {
        this.reader = new ConfigurationClassBeanDefinitionReader(
                registry, this.sourceExtractor, this.resourceLoader, this.environment,
                this.importBeanNameGenerator, parser.getImportRegistry());
    }
    /// 本文介绍的起始点
    this.reader.loadBeanDefinitions(configClasses);
    alreadyParsed.addAll(configClasses);

    candidates.clear();
    if (registry.getBeanDefinitionCount() > candidateNames.length) {
        .
        (省略篇幅)
        .
        candidateNames = newCandidateNames;
    }
}
while (!candidates.isEmpty());

 本文将从this.reader.loadBeanDefinitions(configClasses)开始重点介绍关于文章标题的事情。进入loadBeanDefinitions方法,

public void loadBeanDefinitions(Set<ConfigurationClass> configurationModel) {
    TrackedConditionEvaluator trackedConditionEvaluator = new TrackedConditionEvaluator();
    for (ConfigurationClass configClass : configurationModel) {
        loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator);
    }
}

传入的configurationModel是parser.parse找到的所有配置类和用户自己写的类。大部分框架的配置类都在spring-boot-autoconfigure-2.1.1.RELEASE.jar包的org/springframework/boot/autoconfigure/*路径下。f

  • 5
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值