SpringBoot自动装配流程

7 篇文章 0 订阅
2 篇文章 0 订阅
本文详细解释了SpringBoot的自动装配过程,涉及`@SpringBootApplication`注解的拆分、`AutoConfigurationPackages`和`AutoConfigurationImportSelector`类的作用,以及如何通过源码分析理解自动配置的加载和排除机制。
摘要由CSDN通过智能技术生成

SpringBoot自动装配流程

准备工作

@SpringBootApplication
public class SpringStartProcessApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringStartProcessApplication.class,args);
    }
}

拆分@SpringBootApplication注解

# 标注该类是主启动类
@SpringBootApplication
    @SpringBootConfiguration
        # 配置类
        @Configuration
        # 加快SpringBoot启动
        @Indexed
    # 开启自动装配
    @EnableAutoConfiguration
        # 设置扫描包的路径
        @AutoConfigurationPackage
            # 导入一个类
            @Import(AutoConfigurationPackages.Registrar.class)
        # 加载META-INF/spring.factories,将beandefinitions装入容器
        @Import(AutoConfigurationImportSelector.class)
    # 用来排除一些自动配置类
    @ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
    		@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })

接下来重点关注AutoConfigurationPackages.Registrar类和AutoConfigurationImportSelector

AutoConfigurationPackages.Registrar

先在AutoConfigurationPackages.Registrar的图示位置打上断点,接着启动程序

在这里插入图片描述

分析源码要由内而外的分析

方法参数中有一个new出来的对象,直接单步调试进去

在这里插入图片描述

1、metadata到底是哪个类的注解元信息?

其实是启动类的,也就是SpringStartProcessorApplication

2、这个basePackages和basePackageClasses在哪里体现的呢?

在这里插入图片描述

其实是在SpringBootApplication注解上

在这里插入图片描述

这也就说明这个metadata包括了@SpringBootApplication标注的类上的其他注解的元信息和自身内部的注解的元信息

在这里插入图片描述

ok这段代码解决,现在继续点进去,看这个register方法里面写了啥

在这里插入图片描述

AutoConfigurationImportSelector

在这里插入图片描述

既然知道了这个类的作用,所以找到selectImports方法,打上断点,启动程序等待程序停止

但是!你会发现断点并没有生效

实际上断点应该打在AutoConfigurationGroup类的process方法

在这里插入图片描述

点进getAutoConfigurationEntry方法

在这里插入图片描述

ps:这里的attributes是取出exclude和excludeName,就是用于排除掉不需要加载的自动配置类
这两个属性是在@SpringBootApplication中配的,是从@EnableConfiguration中得来的
在这里插入图片描述

在这里插入图片描述

getCandidateConfigurations

在这里插入图片描述

点进SpringFactoriesLoader.loadFactoryNames方法

在这里插入图片描述

点进loadSpringFactories方法

在这里插入图片描述

然后在这里就会发现这个result竟然不是null,直接返回了result

哎不是,我还没执行下面的逻辑呢,怎么就走缓存了

其实这步加载在刚开始的时候就做了,所以直接在下面打一个断点,然后重新执行

你会发现之前的那些断点都没有起作用,而是直接停在了这一行
在这里插入图片描述

现在找一下auto-configuration包下的META-INF/spring.factories文件

在这里插入图片描述

可以看到这些类都有一个统一的特征,那就是都是以AutoConfiguration结尾

在这里插入图片描述

随便点开一个看,发现都长得差不多

在这里插入图片描述

注意:这里会加载类路径下所有的META-INF/spring.factories文件

每一个url就是一个jar包下的META-INF/spring.factories文件

在这里插入图片描述

在这里插入图片描述

好,现在我们加载了所有jar包下的META-INF/spring.factories文件

现在放行,一直到这一步

在这里插入图片描述

为什么要框住131这个数字?

你现在回到刚刚那个spring.factories文件

数一下org.springframework.boot.autoconfigure.EnableAutoConfiguration后面有几个类的全限定名

在这里插入图片描述

对,正正好好131个

removeDuplicates

在这里插入图片描述

这个方法就是给list去重的,简单的赖,我来我也行!

为什么要做去重?这个文件不是spring自己写的吗?它自己还不敢确定这个类不会重复吗?

刚刚提到了,这里会加载所有类路径下的spring.factories文件,所以我如果这样呢
我在我自己的类路径下面创建一个spring.factories文件

在这里插入图片描述

内容如下

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration

Spring能确认自己写的不会重复,但是它不能保证你不加个重复的啊

getExclusions

在这里插入图片描述

checkExcludedClasses

检查排除的类是否在org.springframework.boot.autoconfigure.EnableAutoConfiguration配置中

如果不存在则不允许排除,抛出异常
在这里插入图片描述

在这里插入图片描述

configurations.removeAll(exclusions);

即将configurations排除exclusions

getConfigurationClassFilter().filter(configurations);

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在过滤后,configurations就只剩下可怜的13个了

在这里插入图片描述

fireAutoConfigurationImportEvents

这个不太确定
在这里插入图片描述

最后就将其封装成AutoConfigurationEntry对象返回

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

芝麻\n

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值