SpringBoot3自动配置原理

​​​​​​自动配置

遵循约定大约配置的原则,在boot程序启动后,起步依赖中的一些bean对象会自动注入到ioc容器

看一下我们前面写的代码有没有达到自动配置的效果呢?

没有自动,我们写了配置类,写了@Import注解,所以并没有达到自动配置的效果。那怎么办呢?接下来我们通过翻看源码的方式来了解一下SpringBoot自动配置是怎么回事!了解完毕之后我们照葫芦画瓢就可以解决问题!

自动配置-源码分析

程序引入spring-boot-starter-web 起步依赖,启动后,会自动往ioc容器中注入DispatcherServlet

接下来我们验证一下,看它有没有自动注入DispatcherServlet

创建一个SpringBoot工程

这里没有 web起步依赖

XML 复制代码
 <dependencies>
        <!--springboot核心起步依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

主启动

java 复制代码
@SpringBootApplication
public class SpringbootAutoConfigApplication {
​
    public static void main(String[] args) {
        ApplicationContext context = SpringApplication.run(SpringbootAutoConfigApplication.class, args);
        System.out.println(context.getBean("dispatcherServlet"));
    }
}

这时候工程里面没有 web起步依赖 就没有 DispatcherServlet,这里就会报错

导入 web起步依赖

XML 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

那就验证了之前的话,如果你引入了web起步依赖,就会自动往ioc容器中注入一个DispatcherServlet,那SpringBoot如何做到的呢?接下来就要翻一下源码了。

源码解读

@SpringBootApplication 注解

我们进入这个注解,它的头上怎么顶着这么多注解,不过真正重要的只有三个注解,我们接下来会 一 一介绍。

@Target(ElementType.TYPE) //元注解,可以在类上面使用 @Retention(RetentionPolicy.RUNTIME) //元注解,运行时阶段

@Documented //生成Java文档

@Inherited //是一个标识,用来修饰注解

@SpringBootConfiguration 注解

点进@SpringBootConfiguration注解,可以发现其核心注解为@Configuration注解:

@Configuration注解是Spring框架的注解之一,用于标记配置类。 在Spring Boot中,使用@Configuration注解可以将该类作为配置类,从而使该类中的Bean可以被Spring IoC容器管理和使用。

在配置类中,我们可以使用另外两个注解@Bean和@Scope来定义Bean,其中@Bean注解用于定义Bean对象,而@Scope注解用来指定Bean对象的作用域。

总的来说,@Configuration注解能够将一个类定义为Spring Boot应用程序中的配置类,从而使该类中的Bean对象能够被Spring IoC容器进行自动管理和装配。这让应用开发者能够更加专注于应用逻辑的实现,而不必花费精力在繁琐的配置上。 所以**@SpringBootConfiguration** 注解本质上就是一个**@Configuration** 注解,用来标注某个类为 JavaConfig 配置类,有了这个注解就可以在 SpringBoot 启动类中使用**@Bean**标签配置类了。

@ComponentScan 注解

@ComponentScan 是 Spring Framework 中的一个注解,它用于指定 Spring 容器需要扫描和管理的组件。组件是 Spring 中的一个抽象概念,它包括了 Spring Bean、Controller、Service、Repository 等等。通过 @ComponentScan 注解,可以让 Spring 容器自动扫描和管理这些组件,从而简化应用程序的配置和管理。 @ComponentScan 注解有多个参数,可以用于指定要扫描的组件的位置、排除不需要扫描的组件、指定要排除扫描的组件等等。

默认情况下,Spring Boot会自动扫描主应用程序下的所有组件(@Configuration, @Controller, @Service, @Repository等),但是如果你将组件放在其他包下,那么就需要显式地配置扫描目录。

@EnableAutoConfiguration 注解

这是今天的主角中的主角,自动配置实现的核心注解。 点进这个注解可以发现,如下图所示。

我们重点来看 **@Import(AutoConfigurationImportSelector.class)**这个注解。 @Import 注解是 它用于将一个或多个类导入到 Spring 容器中,以便于在应用程序中使用。通过 @Import 注解,我们可以将一些非 Spring 管理的类实例化并注册到 Spring 容器中,或者将一些 Spring 管理的配置类导入到当前配置类中,以便于在应用程序中进行统一的配置和管理。 @Import是Spring Framework 中的一个注解,用于在配置类中导入其他配置类或者普通的Java类。

说白了在这里@Import注解的作用就是将 AutoConfigurationImportSelector这个类导入当前类,这个类就是实现自动配置的核心。 我们继续进入到 AutoConfigurationImportSelector 类:

AutoConfigurationImportSelector实现了DeferredImportSelector接口,我们进入DeferredImportSelector接口

最后,我们发现, AutoConfigurationImportSelector 实际上是实现了 ImportSelector接口,这个接口只有两个方法,其中我们需要重点关注 **selectImports()**方法。

ImportSelector 接口是 Spring Framework 中的一个接口,它可以用于在 Spring 容器启动时动态地导入一些类到 Spring 容器中。通过实现 ImportSelector 接口,并重写其中的 selectImports 方法,我们可以自定义逻辑来确定需要导入的类,从而实现更加灵活的配置和管理。

selectImports 方法是 ImportSelector 接口中的一个方法,用于返回需要导入的类的全限定类名数组。在 Spring 容器启动时,Spring 会扫描所有实现了 ImportSelector 接口的类,并调用其中的 selectImports 方法来确定需要导入的类。

我们进入**getAutoConfigurationEntry()**方法

这里返回AutoConfigurationEntry类,里面传入了 configurations和exclusions两个参数, configurations参数通过getCandidateConfigurations() 方法得到,我们进入**getCandidateConfigurations()**方法。

Assert.notEmpty这是一个断言,configurations不能为空 ,如果为空了,给你一段提示:没有自动配置的类找到,在 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports找到,我们将这端配置简称为 .imports 文件,意思就是说,我要去找自动配置类 去**.imports**中找,但是我并没有找到,我们需要关注这个配置文件在什么地方,这里先回到pom.xml文件中

进去核心起步依赖,这里面引入了一个:spring-boot-autoconfigure,autoconfigure顾名思义就是自动配置的意思。

接下来我们去找到autoconfigure

在这里我们找到了 AutoConfiguration.imports配置文件

点进去,这个配置文件其实就是配置了一堆类的全类名,这些类都是自动配置类,接下来我们去看看之前演示的DispatcherServlet相关的自动配置类 Ctrl+F:搜索一下

进入:DispatcherServletAutoConfiguration类 , Ctrl+Shift+N全局搜索进入这个类

**@AutoConfiguration(after = {ServletWebServerFactoryAutoConfiguration.class})**顾名思义,自动配置的意思

@AutoConfiguration点进去,你会发现它也是一个组合注解,组合了一个@Configuration()

说白了DispatcherServletAutoConfiguration这个类是一个配置类

这个类用了@AutoConfiguration注解,更加见名之意它是一个配置类

我们再看**@ConditionalOnClass**这个注解,是不是很熟悉,前面讲到过:它在这里的意思是,如果你环境里面有DispatcherServlet,那自动配置类就会生效自动注入一个DispatcherServlet的bean对象,如果环境里没有DispatcherServlet,那就不生效,不注入了。

接下来继续往下看

这里内部有一个DispatcherServletConfiguration类,也配置@Configuration注解,里面写一个方法,方法最终返回的就是dispatcherServlet,方法上面有@Bean注解,最终我们可以看到,它注入DispatcherServlet的代码在这里,其实你会发现这里的代码和我们之前写的代码并没有很大的区别,都是写一个方法,让后在方法上面声明一个@Bean注解。

这里最核心的是,它把这个类DispatcherServletAutoConfiguration写到指定的配置文件里面了,那么SpringBoot就可以自动的去读取这个全类名,把这个配置的类的对象注入到Ioc容器中,由于这个配置类的内部还有配置类DispatcherServletConfiguration,内部的配置类里面还有一些方法,这些方法声明了@Bean注解,所以SpringBoot它会继续解析,直到把这些@Bean注解的方法都解析到,执行这些方法,然后把返回值注入到IOC容器里。

因此我们自动配置的核心在哪?核心核心,在这个.imports配置文件中,那么源码我们就到这。

小总结

在SpringBoot2.7版本以前,它自动配置使用的配置文件是 spring.factories,它会从 spring.factories配置文件中读取配置类的全类名,那么在SpringBoot2.7以后到3.0以前,它同时兼容了.imports配置文件以及spring.factories配置文件,在3.0以后只支持.imports配置文件,这个大家要清楚。

通过源码分析,我们知道了,SpringBoot自动配置无非就是提供一个自动配置类,把这个类名写到指定的配置文件中就可以了。

说一说SpringBoot自动配置原理?

希望可以帮到大家,喜欢的给冯宝宝点个关注把,蟹蟹支持!!

相关推荐
苹果醋326 分钟前
Java8->Java19的初步探索
java·运维·spring boot·mysql·nginx
Wx-bishekaifayuan40 分钟前
django电商易购系统-计算机设计毕业源码61059
java·spring boot·spring·spring cloud·django·sqlite·guava
customer0844 分钟前
【开源免费】基于SpringBoot+Vue.JS周边产品销售网站(JAVA毕业设计)
java·vue.js·spring boot·后端·spring cloud·java-ee·开源
Yaml42 小时前
智能化健身房管理:Spring Boot与Vue的创新解决方案
前端·spring boot·后端·mysql·vue·健身房管理
LuckyLay2 小时前
Spring学习笔记_27——@EnableLoadTimeWeaving
java·spring boot·spring
佳佳_3 小时前
Spring Boot 应用启动时打印配置类信息
spring boot·后端
程序媛小果4 小时前
基于java+SpringBoot+Vue的宠物咖啡馆平台设计与实现
java·vue.js·spring boot
狂放不羁霸6 小时前
idea | 搭建 SpringBoot 项目之配置 Maven
spring boot·maven·intellij-idea
计算机学长felix7 小时前
基于SpringBoot的“校园交友网站”的设计与实现(源码+数据库+文档+PPT)
数据库·spring boot·毕业设计·交友
码农派大星。7 小时前
Spring Boot 配置文件
java·spring boot·后端