• springboot启动自动配置原理分析


    先从启动配置注解 SpringbootApplication来看,点开查看。
    最上面的四个是元注解。
    主要是下面的三个注解。

    在这里插入图片描述

    第一个:@SpringBootConfiguration, 点进去查看,

    在这里插入图片描述
    可以看到,主要是一个Configuration 注解,标识这个类是配置类。

    第三个(第二个在下面看):@ComponentScan

    指定组件扫描的路径,指定扫描哪些组件。

    第二个是核心 ,@EnableAutoConfiguration

    点击进入查看也有两个核心注解:
    在这里插入图片描述
    1,第一个:@AutoConfigurationPackage, 点进去查看。有一个@Import注解导入了一个Registter。
    在这里插入图片描述
    这里实际上使用Register 导入了一堆组件,并不是只导入了这一个组件,进入Register,
    会调用这里的方法。
    在这里插入图片描述

    至于为什么这个可以看Import 注解的作用,高级用法。
    在这里插入图片描述

    这里第一个方法的参数是一个注解的元信息, 这个注解是谁?我们从AutoConfigurationPackage跳过来的,这个注解就是这个。 而注解的元信息表示注解标在了哪个类上,其属性值是什么。
    在该方法上加个断点debug:
    在这里插入图片描述
    这个注解标注的类在启动类MainApplication上,因为@SpringBootApplication是一个合成注解,包含这个AutoConfigurationPackage。所以从debug信息中可以看到MainApplication,如下:
    在这里插入图片描述
    然后这个方法干了啥呢?

     public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
     AutoConfigurationPackages.register(registry, (String[])(new AutoConfigurationPackages
     			.PackageImports(metadata))
                .getPackageNames()
                .toArray(new String[0]));
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    先new 了一个对象,拿到元信息metadata,然后获取的报名,即这一段代码:new AutoConfigurationPackages
    .PackageImports(metadata))
    .getPackageNames()
    这一段拿到了启动类所在的包路径:如下:
    在这里插入图片描述
    最后一个.toArray(new String[0])); 将所有该包下组件都放入到一个数组中了(这里就不要理解为转成一个数组了,放到一个数组最好了)。
    然后通过AutoConfigurationPackages.register,注册进去。
    这就解释了为什么用Springboot时,默认的包路径?是启动类所在的包。。。

    2,然后看@EnableAutoConfiguration 的第二个注解了@Import({AutoConfigurationImportSelector.class}) ,这个使用了AutoConfigurationImportSelector 类。进入这个类里面查看
    在这里插入图片描述
    这个selectImports 指定要导入哪些,都放到String数组返回,根据这个数组来确定。
    所以核心都落在了this.getAutoConfigurationEntry 这个方法上了。
    跳到这个方法,打一个断点debug:
    在这里插入图片描述

    拿到configurations 大小有127个。这是拿到127个组件,这些是默认导入到容器中的组件。
    单步进入:进入这个方法查看:使用的SpringFactoriesLoader 加载
    在这里插入图片描述
    在进入这个loadFactoryNames 方法
    在这里插入图片描述

    再进入这个loadSpringFactories方法:最后返回的是一个map list集合。
    在这里插入图片描述

    初始时上面方法的result 必定是空的,所以会优先执行else 的语句块
    在这里插入图片描述
    这里会加载当前工程下所有包,包括导入的包MET-INF 下的spring.factories。
    在这里插入图片描述
    有些jar包就没有这个spring.factories
    在这里插入图片描述
    但是springboot的包下就存在这个springboot.factories
    在这里插入图片描述
    但是前面的127个组件,实际上是autoconfigration 包下的spring.factories所指定的自动配置类。
    在这里插入图片描述
    但是这127个没有全部放入到springboot的容器中,有些是生效的有些是没有生效的。这127个默认场景的是
    ** 默认全部加载,但是最终会按需配置。 **
    这些配置是根据标在它上面的@Conditional相关注解判断是否生效。
    例如:下面的aop 配置,只有Advice 类存在这个配置类才会生效。
    在这里插入图片描述
    其他的autoconfigure类也相同。

    总结:

    @SpringBootConfiguration :指定了当前类是一个配置类 。
    @ComponentScan : 指定扫描的包路径。
    @EnableAutoConfiguration 的@AutoConfigurationPackage 确定了启动类所在的包。
    @EnableAutoConfiguration 的@Import({AutoConfigurationImportSelector.class}) :确定了要加载的所有场景的自动配置类,并根据application.properties文件按需进行配置。

  • 相关阅读:
    MySql逗号分割的字段数据分解为多行
    合作QA是大聪明?撸个接口校验工具保命(5)
    【计算机网络】IP协议第二讲(Mac帧、IP地址、碰撞检测、ARP协议介绍)
    C++智能指针详解
    BlenderGIS插件 城市建筑3D模型自动生成 教程
    小鼠血清白蛋白包裹四氧化三铁纳米粒
    MySql总结
    FOFAHUB使用测试
    颜色的感知
    javacc之路1--- Token Manager
  • 原文地址:https://blog.csdn.net/qq_45860901/article/details/126869529