SpringBoot自动装配原理(源码篇)

目录

1、源码分析

2、注解分析 

 2.1、@SpringBootApplication是一个复合注解

3、@SpringBootConfiguration

4、@ComponentScan

5、@EnableAutoConfiguration

6、自动装配本质


1、直接请出源码分析,咳咳,当然先创建一个无任何依赖和starter的空项目

注意:在选择SpringBoot版本时,如果你的jdk是1.8,那么不要选择3.0以上的版本,因为3.0以上的版本需要jdk17的支持,会报错Java错误:“无效的源发行版:17”。

接下来运行该空项目。

正常启动。

2、从@SpringBootApplication开始分析 

 2.1、@SpringBootApplication是一个复合注解

查看源码之后,发现主要有以下三个注解组成:

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan

3、@SpringBootConfiguration

这里我们直接对标源码进行简单分析

这里的@Configuration是一个JavaConfig的配置类

那么问题来了,JavaConfig是干什么的呢?

答:JavaConfig是用来配置Bean的,之前说明了@SpringBootApplication是一个复合注解,它包含了@Configuration,所以我们在SpringBoot主类中可以使用@Bean注解配置类。

@SpringBootApplication
public class BootAutoWrieApplication {
    public static void main(String[] args) {

        SpringApplication.run(BootAutoWrieApplication.class, args);

    }
    @Bean
    public  HelloWorld helloWorld(){
        return new HelloWorld();
    }
}

 4、@ComponentScan

这个注解是组件扫描的意思,扫描范围是:SpringBoot主启动类的同级路径及其子路径,扫描范围如下:

5、@EnableAutoConfiguration

这个注释是最核心的内容,那么话不多说,进入@EnableAutoConfiguration:

图中画圈位置的注解为 @Import(AutoConfigurationImportSelector.class),这里的作用便是导入了AutoConfigurationImportSelector这个类的bean定义

AutoConfigurationImportSelector 这个类是实现了ImportSelector接口,因此我们找到这个重写的方法如下:

PS:代码好长,一行放不下

这个方法的返回类型是一个字符串数组String[],那么即使这个类再怎么长,返回的也一定是一个字符串数组

 这个字符串数组存放的是什么呢?返回结果是要加载的Config配置文件的全包名,通过返回这个全包名,就能自动装配这些配置文件下定义的bean对象,从而达到了自动装配的目的

在这个方法中肯定是有一个注解类名字来查找相应的Config文件的操作的,我们看到以下代码:

在这里我们发现 autoConfigurationEntry中保存着我们需要的配置信息,是通过getAutoConfigurationEntry方法来获取的。

接下来我们进入getAutoConfigurationEntry方法查看源码。

仔细看这个方法返回的是新建立的AutoConfigurationEntry对象,根据构造函数来看,他给了两个参数分别是configurations, exclusions。

configurations一定是我们所需要的配置文件,而exclusions字面意思是排除,也就是不需要的。

6、自动装配本质

(1)Spring Boot自动装配的本质就是通过Spring来读取META-INF/spring.factories中保存的配置类文件,然后加载bean定义的过程。

(2)如果有标注@Configuration注解,就是批量加载了里面的定义。

(3)实现自动配置方法:通过配置文件获取对应的批量配置类,然后通过配置类批量加载bean定义,只要有写好的配置文件,spring.factories就实现了自动。


版权声明:本文为weixin_55075130原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。