Springboot下Mybatis源码

1.使用

dependencies {    compile 'mysql:mysql-connector-java:8.0.22'    compile 'org.mybatis.spring.boot:mybatis-spring-boot-starter:2.1.3'}

2.启动加载

SPI机制:

加载时机:

public void refresh() throws BeansException, IllegalStateException {    synchronized(this.startupShutdownMonitor) {        //准备工作,记录容器的启动时间、标记“已启动”状态、检查环境变量等        prepareRefresh();        //创建一个默认的BeanFactory: DefaultListableBeanFactory,并加载BeanDefinition        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();        /*对Bean工厂进行属性填充:            1.设置类加载器,bean表达式解释器,忽略给定接口的自动装配功能            2.添加了ApplicationContextAwareProcessor(获取 applicationContext上下文,资源,系统参数等)            ApplicationListenerDetector后置处理器(检测容器中的ApplicationLisenter,将其注册到上下文中)*/        prepareBeanFactory(beanFactory);        try {            //目前没有任何实现            postProcessBeanFactory(beanFactory);            /*            拿到所有自定义和内置的BeanDefinitionRegistryPostProcessor后置处理器,循环调用postProcessBeanDefinitionRegistry;            其中最重要的是ConfigurationClassPostProcessor处理器的执行:遍历BeanDefinition找到带有@Configuration注解的BeanDefinition,            解析处理配置类中的@Import,@PropertySources,@ComponentScans(如果存在注解,则会扫描对应路径的类转换成BeanDefinition,存入BeanDefinitionMap),@Bean(同样)注解等            */        invokeBeanFactoryPostProcessors(beanFactory);        //注册BeanPostProcessor后置处理器            registerBeanPostProcessors(beanFactory);            //初始化消息资源解析器            initMessageSource();            //初始化注册一个单列ApplicationContext事件监听器applicationEventMulticaster            initApplicationEventMulticaster();            //容器初始化扩展方法,交给子类实现            onRefresh();            //注册事件监听器,派发容器初始化的事件:监听器需要实现ApplicationListener接口            registerListeners();            //实例所有的单例Bean,创建单例非懒加载的bean            finishBeanFactoryInitialization(beanFactory);            //容器初始化完成            finishRefresh();        } catch (BeansException var9) {            if (logger.isWarnEnabled()) {                logger.warn("Exception encountered during context initialization - cancelling refresh attempt: "   var9);            }            destroyBeans();            cancelRefresh(var9);            throw var9;        } finally {            resetCommonCaches();        }    }}
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {    // 获取容器中的BeanFactoryPostProcessor(注意这里自定义的BeanFactoryPostProcessor还没有初始化)    // getBeanFactoryPostProcessors()方法一般是获取不到值的,除非我们手动调用addBeanFactoryPostProcessor方法或注解@Component来注入BeanFactoryPostProcessors对象    // 重点关注ConfigurationClassPostProcessor    PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, this.getBeanFactoryPostProcessors());        if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {            beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));            beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));        }}

 PostProcessorRegistrationDelegate类下:

public static void invokeBeanFactoryPostProcessors(        ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {    Set<String> processedBeans = new HashSet<>();   //开始处理BeanDefinitionRegistryPostProcessor    // 判断beanFactory是否为BeanDefinitionRegistry,beanFactory为DefaultListableBeanFactory,而DefaultListableBeanFactory实现了BeanDefinitionRegistry接口,因此为true    if (beanFactory instanceof BeanDefinitionRegistry) {        BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;        // 用于存放普通的BeanFactoryPostProcessor        List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();        // 用于存放BeanDefinitionRegistryPostProcessor        List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();        // 首先处理入参中的beanFactoryPostProcessors,遍历区分BeanDefinitionRegistryPostProcessor和普通BeanFactoryPostProcessor        for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {            if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {                BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor;                // 执行BeanDefinitionRegistryPostProcessor接口的postProcessBeanDefinitionRegistry方法                registryProcessor.postProcessBeanDefinitionRegistry(registry);                // 添加到registryProcessors(用于最后执行postProcessBeanFactory方法)                registryProcessors.add(registryProcessor);            }else {                // 添加到regularPostProcessors(用于最后执行postProcessBeanFactory方法)                regularPostProcessors.add(postProcessor);            }        }        // 首先,调用实现PriorityOrdered的BeanDefinitionRegistryPostProcessors        // 用于保存本次要执行的BeanDefinitionRegistryPostProcessor。        List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();        // 找出所有实现BeanDefinitionRegistryPostProcessor接口的Bean的beanName        String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);        for (String ppName : postProcessorNames) {            // 校验是否实现了PriorityOrdered接口            if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {                currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));                processedBeans.add(ppName);            }        }        // 进行排序(根据是否实现PriorityOrdered、Ordered接口和order值来排序)        sortPostProcessors(currentRegistryProcessors, beanFactory);        // 合并        registryProcessors.addAll(currentRegistryProcessors);        // 遍历currentRegistryProcessors, 执行postProcessBeanDefinitionRegistry方法     invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);      // 清空currentRegistryProcessors        currentRegistryProcessors.clear();        ...省略    }    ...省略}

原因:

public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor,        PriorityOrdered, ResourceLoaderAware, BeanClassLoaderAware, EnvironmentAware {...}

ConfigurationClassPostProcessor类下解析spring.factories文件:

@Overridepublic void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {    ...省略    // 执行postProcessBeanDefinitionRegistry方法    processConfigBeanDefinitions(registry);}public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {    List<BeanDefinitionHolder> configCandidates = new ArrayList<>();    // 获取Spring容器中目前所有BeanDefinition的名称    String[] candidateNames = registry.getBeanDefinitionNames();    // 遍历判断是否有没有解析过    for (String beanName : candidateNames) {        BeanDefinition beanDef = registry.getBeanDefinition(beanName);        if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {            if (logger.isDebugEnabled()) {                logger.debug("Bean definition has already been processed as a configuration class: "   beanDef);            }        }        // 判断是否是配置类        else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {            configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));        }    }    // 如果未找到@Configuration类,则立即返回    if (configCandidates.isEmpty()) {        return;    }    // 按@Order值排序    configCandidates.sort((bd1, bd2) -> {        int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());        int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());        return Integer.compare(i1, i2);    });    // 创建@CompentScan、@Import导入进来的bean名称的生成器    SingletonBeanRegistry sbr = null;    if (registry instanceof SingletonBeanRegistry) {        sbr = (SingletonBeanRegistry) registry;        if (!this.localBeanNameGeneratorSet) {            BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(                    AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR);            if (generator != null) {                this.componentScanBeanNameGenerator = generator;                this.importBeanNameGenerator = generator;            }        }    }    // 如果系统环境为空则构建系统环境    if (this.environment == null) {        this.environment = new StandardEnvironment();    }    // 解析每个@Configuration类    ConfigurationClassParser parser = new ConfigurationClassParser(            this.metadataReaderFactory, this.problemReporter, this.environment,            this.resourceLoader, this.componentScanBeanNameGenerator, registry);    // 创建一个集合用于保存我们的配置类BeanDefinitionHolder集合默认长度是配置类集合的长度    Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);    // 创建一个集合用于保存我们的已经解析的配置类,长度默认为解析出来默认的配置类的集合长度    Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());    do {        // 真正的解析我们的配置类        parser.parse(candidates);        parser.validate();        // 解析出来的配置类        Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());        configClasses.removeAll(alreadyParsed);        // Read the model and create bean definitions based on its content        if (this.reader == null) {            this.reader = new ConfigurationClassBeanDefinitionReader(                    registry, this.sourceExtractor, this.resourceLoader, this.environment,                    this.importBeanNameGenerator, parser.getImportRegistry());        }        // 在此之前仅仅只是解析完成,并未注册到Spring容器中,然后将解析出来的配置类转换成BeanDefinition并注册到Spring 容器中        this.reader.loadBeanDefinitions(configClasses);        alreadyParsed.addAll(configClasses);        candidates.clear();        //判断 Spring 容器中Bean的定义数量是否 > 候选原始的bean定义的个数        if (registry.getBeanDefinitionCount() > candidateNames.length) {            // 获取所有的bean定义            String[] newCandidateNames = registry.getBeanDefinitionNames();            // 原始的bean定义            Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));            Set<String> alreadyParsedClasses = new HashSet<>();            // 赋值已经解析的            for (ConfigurationClass configurationClass : alreadyParsed) {                alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());            }            // 判断是否有漏掉没有解析的配置类            for (String candidateName : newCandidateNames) {                if (!oldCandidateNames.contains(candidateName)) {                    BeanDefinition bd = registry.getBeanDefinition(candidateName);                    if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&                            !alreadyParsedClasses.contains(bd.getBeanClassName())) {                        candidates.add(new BeanDefinitionHolder(bd, candidateName));                    }                }            }            candidateNames = newCandidateNames;        }    }    // 循环解析    while (!candidates.isEmpty());    // 将ImportRegistry注册为Bean,以支持ImportAware @Configuration类    if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {        sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());    }    // 清除缓存    if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {        ((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();    }}public void parse(Set<BeanDefinitionHolder> configCandidates) {    for (BeanDefinitionHolder holder : configCandidates) {        BeanDefinition bd = holder.getBeanDefinition();        try {            if (bd instanceof AnnotatedBeanDefinition) {                // 如果bean实现自 AnnotatedBeanDefinition 接口,则进行注解bean定义的解析                parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());            }            else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) {                // 如果bean实现自 AbstractBeanDefinition 接口,则进行抽象bean定义的解析                parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName());            }            else {                // 常规配置类进行解析                parse(bd.getBeanClassName(), holder.getBeanName());            }        }        ...    }    //这里会加载解析spring.properties中的配置类    this.deferredImportSelectorHandler.process();}public void process() {    List<DeferredImportSelectorHolder> deferredImports = this.deferredImportSelectors;    this.deferredImportSelectors = null;    try {        if (deferredImports != null) {            DeferredImportSelectorGroupingHandler handler = new DeferredImportSelectorGroupingHandler();            deferredImports.sort(DEFERRED_IMPORT_COMPARATOR);            deferredImports.forEach(handler::register);            handler.processGroupImports();        }    }    finally {        this.deferredImportSelectors = new ArrayList<>();    }}public void processGroupImports() {    for (DeferredImportSelectorGrouping grouping : this.groupings.values()) {        Predicate<String> exclusionFilter = grouping.getCandidateFilter();        grouping.getImports().forEach(entry -> {            ConfigurationClass configurationClass = this.configurationClasses.get(entry.getMetadata());            try {                processImports(configurationClass, asSourceClass(configurationClass, exclusionFilter),                        Collections.singleton(asSourceClass(entry.getImportClassName(), exclusionFilter)),                        exclusionFilter, false);            }            ...        });    }}public Iterable<Group.Entry> getImports() {    for (DeferredImportSelectorHolder deferredImport : this.deferredImports) {        this.group.process(deferredImport.getConfigurationClass().getMetadata(),                deferredImport.getImportSelector());    }    return this.group.selectImports();}public void process(AnnotationMetadata annotationMetadata, DeferredImportSelector deferredImportSelector) {    Assert.state(deferredImportSelector instanceof AutoConfigurationImportSelector,            () -> String.format("Only %s implementations are supported, got %s",                    AutoConfigurationImportSelector.class.getSimpleName(),                    deferredImportSelector.getClass().getName()));    AutoConfigurationEntry autoConfigurationEntry = ((AutoConfigurationImportSelector) deferredImportSelector)            .getAutoConfigurationEntry(annotationMetadata);    this.autoConfigurationEntries.add(autoConfigurationEntry);    for (String importClassName : autoConfigurationEntry.getConfigurations()) {        this.entries.putIfAbsent(importClassName, annotationMetadata);    }}protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {    if (!isEnabled(annotationMetadata)) {        return EMPTY_ENTRY;    }    AnnotationAttributes attributes = getAttributes(annotationMetadata);    List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);    configurations = removeDuplicates(configurations);    Set<String> exclusions = getExclusions(annotationMetadata, attributes);    checkExcludedClasses(configurations, exclusions);    configurations.removeAll(exclusions);    configurations = getConfigurationClassFilter().filter(configurations);    fireAutoConfigurationImportEvents(configurations, exclusions);    return new AutoConfigurationEntry(configurations, exclusions);}protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {    List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),            getBeanClassLoader());    Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you "              "are using a custom packaging, make sure that file is correct.");    return configurations;}public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {    String factoryTypeName = factoryType.getName();    return loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList());}

View Code

来源:https://www.icode9.com/content-1-768101.html

(0)

相关推荐

  • 通过Spring注解注册Bean的四种方式

    文章目录 包扫描+组件标注注解 @Bean注解 @Import注解 使用FactoryBean(工厂Bean) 给spring容器中注册bean有四种通过注解的方式: 包扫描+组件标注注解 @Bean ...

  • Spring 手动注册bean

    一般情况下,我们Spring应用中的bean都是通过注解或者xml注入到容器中的,有些情况下我们可能想手动往容器中注入bean,即编程方式注入bean. 本文所使用源码包版本:spring-beans ...

  • Spring框架之beans源码完全解析

    导读:Spring可以说是Java企业开发里最重要的技术.而Spring两大核心IOC(Inversion of Control控制反转)和AOP(Aspect Oriented Programmin ...

  • 死磕Spring之IoC篇 - 深入了解Spring IoC(面试题)

    该系列文章是本人在学习 Spring 的过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring 源码分析 GitHub 地址 进行阅读 Spring 版本:5.1. ...

  • Java高并发21-AQS在共享,独占场景下的源码介绍

    一.AQS--锁的底层支持 1.AQS是什么 AQS是AbstractQueuedSychronizer的简称,即抽象同步队列的简称,这是实现同步器的重要组件,是一个抽象类,虽然在实际工作中很烧用到它 ...

  • 通达信选股指标 上天堂下地狱 源码,不加密,通达信,选股公式,股票指标公式分享平台

    指标公式描述 BB:=EMA(EMA(EMA(C,3),3),3); A:=EMA(EMA(EMA(C,5),5),5); C=HHV(C,21) AND CROSS(BB,A) AND A>R ...

  • mybatis源码分析(一) 配置文件的解析过程

    mybatis的源码有人已经做过一个中文的注释,代码github上有mybatis中文注释源码 mybatis框架有两个非常重要的xml文件,一个是mybatis的config文件,一个就是mappe ...

  • mybatis源码分析(二) 执行过程

    这边博客衔接上一篇mybatis的xml解析的博客,在xml解析完成之后,首先会解析成一个Configuration对象,然后创建一个DefaultSqlSessionFactory的session工 ...

  • 结合Mybatis源码看设计模式——外观模式

    定义 提供了一个统一的接口,用来访问子系统中一群接口 适用场景 子系统复杂,增加外观模式提供简单调用接口 构建多层系统结构,用外观对象作为每层入口 详解 外观模式,主要理解外观.通俗一点可以认为这个模 ...

  • 怒肝一夜 | Mybatis源码深度解析

    回复"面试"获取全套面试资料 本文:12006字,阅读时长:10分15秒 前面已经发过Mybatis源码解析的文章了,本文是对前面文章进行精简以及部分调整优化,总结出来的一篇万字M ...

  • 看到Mybatis源码就感到烦躁,怎么办?

    回复"面试"获取全套面试资料 背景 最近,听到很多吐槽:看到源码,心中就感到十分纠结.特别烦恼. 为什么纠结? 因为面试的时候,面试官很喜欢问:你看过什么框架源码?JDK源码也行. ...

  • Mybatis源码阅读套路,一次性打包发您~

    很多人看源码都不知道如何看,今天来教教大家如何看源码. 前提是我们需要对整个Mybatis的原理.工作流程和模块进行一个整体的直知晓,另外还要有使用经验. 建议先看这两篇文章: 本文主要内容: 源码下 ...

  • 《一本小小的MyBatis源码分析书》.pdf

    回复"面试"获取全套面试资料 什么是MyBatis? MyBatis免除了几乎所有的JDBC代码以及设置参数和获取结果集的工作. MyBatis有什么优点? 与JDBC相比,减少了 ...