• 关于springboot自动配置源码学习


      众所周知,springboot搭建项目相对于spring来说简单快速,因为springboot的原则是约定大于配置,及springboot实现了自动配置。这对于程序员来说大大简化了开发,今天就去看看它是怎么实现的。

      搭建一个简单的springboot项目,在项目目录下可以看到一个springbootApplication的启动类,一切的一切还应该从这个类说起。

      springbootApplication启动类

      

         application类中,标有一个@SpringbootApplication注解,该注解是一个复合注解,主要有@EnableAutoConfiguration和@ComponentScan

                   

        实现自动配置,关键就在于@EnableAutoConfiguration,进入@EnableAutoConfiguration,可以看到@Import({AutoConfigurationImportSelector.class})注解

                    

         进入到AutoConfigurationImportSelector.class中,我们就可以看到springboot大概是怎么实现自动配置的。

       AutoConfigurationImportSelector.class

        AutoConfigurationImportSelector.class实现了DeferredImportSelector接口并重写了selectImports()方法,首先判断环境变量spring.boot.enableautoconfiguration,如果指定为false,则不引入任何类,默认为true;如果为true则进入getAutoConfigurationEntry()方法。

       getAutoConfigurationEntry()方法会做以下逻辑操作:

      1. 获取相应类上@EnableAutoConfiguration对应的属性,其实也就是exclude属性和excludeName属性

      2. 读取classpath环境下所有的META-INFspring.factories文件中的org.springframework.boot.autoconfigure.EnableAutoConfiguration属性,得到configurations集合

      3. 根据第三步读取的配置以及spring.autoconfigure.exclude环境变量指定的配置,得到exclusions集合

      4. 确保exclusions集合是configurations集合的子集,以及exclusions集合内的class均是存在于classpath环境的。否则异常会抛出

      5. 根据上述的exclusions集合筛选出未被过滤的configurations集合。

      6. 根据第7点筛选出来的configurations集合,再在autoConfigurationMetadata的基础上针对ConditionalOnClass属性筛选一轮
        比如:org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration.ConditionalOnClass=org.springframework.cache.CacheManager
        表示如果要应用CacheAutoConfiguration,则得保证org.springframework.cache.CacheManager类存在

      7. 触发AutoConfigurationImportEvent事件

      8. 返回筛选过后的configurations集合

       在第2步中,getCandidateConfigurations(annotationMetadata, attributes)方法中有调用了SpringFactoriesLoader.loadFactoryNames()方法

     

     最后至于说为啥能扫描到注解,查看springboot源码,了解到springboot的启动过程之后会发现SpringApplication类中run() =>prepareContext(context,environment,listeners,applicationArguments,printedBanner)=>load(context, sources.toArray(new Object[0]))=>loader.load()=>load(source)=>this.annotatedReader.register(source)方法,判断springbootApplication启动类是否有@component注解来执行该方法。

    时光静好,与君语;细水长流,与君同;繁华落尽,与君老!
  • 相关阅读:
    面试中遇到递归算法题别慌--常见递归算法题的解题思路
    Xml日志记录文件最优方案(附源代码)
    linux下源码安装软件
    文本比较算法Ⅴ——回顾贴,对前面几篇文章的回顾与质疑
    从内存中直接运行PE程序
    谈谈Linux内核驱动的coding style
    【全面解禁!真正的Expression Blend实战开发技巧】第六章 认识ListBox
    玩转C链表
    麻省理工《C内存管理和C++面向对象编程》笔记---第一讲:认识C和内存管理
    Dll注入技术之输入法注入
  • 原文地址:https://www.cnblogs.com/lyzj/p/13470407.html
Copyright © 2020-2023  润新知