SpringBoot:自动配置原理

SpringBoot 之所以能大幅简化 Spring 应用开发,核心在于其约定大于配置的设计思想,而这一思想主要通过「依赖管理」和「自动配置」两大核心机制落地。本文将从 SpringBoot HelloWorld 程序出发,拆解依赖管理的底层逻辑,以及启动类注解背后的自动配置原理。

一、依赖管理+启动器类注解详情

在传统 Spring 项目中,手动管理依赖版本是开发的一大痛点 ------ 不同依赖的版本不兼容极易导致项目报错。SpringBoot 通过「父项目统一管控 + 场景启动器」的方式,彻底解决了这一问题。

1.依赖管理

①:父项目做依赖管理

SpringBoot 项目的 pom.xml 中,几乎都会继承一个核心父项目,这是依赖管理的基础:

复制代码
<!-- 当前项目的父项目:负责基础依赖管理、资源过滤、插件配置 -->
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.7.14</version>
</parent>

点击进入spring-boot-starter-parent,会发现它还继承了更核心的依赖管理父项目:

复制代码
<!-- 父项目的父项目:几乎声明了所有开发中常用的依赖的版本号 -->
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-dependencies</artifactId>
    <version>2.7.14</version>
</parent>

这里才是真正管理SpringBoot应用里面所有依赖版本的地方,SpringBoot的版本控制重点,

以后我们导入依赖默认是不需要写版本;但是如果导入的包没有在依赖中管理着就需要手动配置版本了;

这里面有咱们所需要的所有版本,这就叫做约定大于配置。

引入官方管控的依赖(如 spring-boot-starter-web、spring-boot-starter-jdbc)时,无需手动指定版本号;

引入非官方管控的依赖(如小众第三方 jar)时,需要手动配置版本;

那么我们如何知道自己引入的jar包,到底需不需要导入版本呀,----你导入jar包的时候看pom文件给不给你提示jar包的版本。

②.starter场景启动器

SpringBoot将所有的功能场景都抽取出来,做成一个个的Starters(启动器),只需要在项目里面引入这些

Starters相关场景的所有依赖都会导入进来。spring-boot-starter-*,官方定义的场景启动器,*代表某种场景;

例如:spring-boot-starter-web:web场景启动器;

spring-boot-starter-jdbc:JDBC 数据库场景;

*-spring-boot-starter,第三方定义的场景启动器;

例如:druid-spring-boot-starter、mybatis-spring-boot-starter;所有场景启动器最底层的依赖

复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
    <version>2.7.14</version>
    <scope>compile</scope>
</dependency>

无需关注版本号,自动版本仲裁

引入版本官方的jar,都可以不写版本;、

引入非版本官方的jar,要写版本号;

可以修改默认版本号

查看spring-boot-dependencies里面规定当前依赖的版本用的key;

在当前项目里面重写配置:

复制代码
<properties>
<mysql.version>5.1.49</mysql.version>
</properties>

2.启动器类注解:自动配置的入口

SpringBoot 项目的核心是启动类,一个简单的注解@SpringBootApplication就能让普通 Java 类变成 SpringBoot 应用的入口,其底层是三个核心注解的组合。

默认的主启动类

复制代码
@SpringBootApplication
public class Springboot01HelloworldApplication {
    public static void main(String[] args) {
        SpringApplication.run(Springboot01HelloworldApplication.class,args);
    }
}

在一个普通的Java类上面添加一个注解@SpringBootApplication,将自动识别为一个SpringBoot的应用程序,该类中的main方法也是SpringBoot程序的入口方法。

@SpringBootApplication注解的源码:

复制代码
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes
= TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes =
AutoConfigurationExcludeFilter.class) })
    public @interface SpringBootApplication {
}

这里又涉及到三个注解@SpringBootConfiguration@ComponentScan@EnableAutoConfiguration

①:@ComponentScan

这个注解在Spring中很重要,它对应XML配置中的包扫描配置。

作用:自动扫描并加载符合条件的组件或者bean,将这个bean定义加载到ioc容器中扫描该注解定义的类所属的包及其子包中的类中注解(@Controller@Service......)

想要改变扫描路径,@SpringBootApplication(scanBasePackages="com.hs");

访问不到,因为扫描包扫描不到这个位置,所以我们需要改变扫描包的扫描地址,以下在启动文件当中启动就行

②:@SpringBootConfiguration

作用:SpringBoot的配置类,标注在某个类上,表示这是一个SpringBoot的配置类;

我们继续进去这个注解查看

复制代码
//点进去得到下面的@component
@configuration
public @interface SpringBootconfiguration {}

@component
public @interface Configuration {}

这里的@Configuration,说明这是一个配置类,配置类就是对应Spring的xml配置.

里面的@Component这就说明,启动类本身也是Spring中的一个组件而已,负责启动应用!

二、依赖管理+启动器类注解详情

1.@EnableAutoConfiguration

作用:开启自动配置功能
以前我们需要自己配置的东西,而现在SpringBoot可以自动帮我们配置;
@EnableAutoConfiguration告诉SpringBoot开启自动配置功能,这样自动配置才能生效;
自动配好Tomcat:

引入Tomcat依赖,web场景启动器依赖了Tomcat的场景启动器;

配置Tomcat

复制代码
dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-tomcat</artifactId>
    <version>2.7.14</version>
    <scope>compile</scope>
</dependency>

自动配好SpringMVC:

引入SpringMVC全套组件,Web场景启动器依赖了Spring和SpringWeb相关的所有组件;

自动配好SpringMVC常用组件(功能),比如DispatcherServlet、CharacterEncodingFilter、MultipartResolver...

复制代码
public static void main(string[] args) {
    //1、runO返回Ioc容器
    ConfigurableApplicationContext context =
        SpringApplication.run(springbootO1HelloworldApplication.class, args);
    //2、查看容器里面的组件
    String[]names=context.getBeanDefinitionNamesO;//获取Ioc容器中所有Bean定义的名称
    for (string name : names) {
        System.out.printIn (name);
    }
}


自动配好Web常见功能,如:字符编码问题:

SpringBoot帮我们配置好了所有web开发的常见场景

2.@AutoConfigurationPackage

点击进入@EnableAutoConfiguration注解当中

复制代码
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
    
}

这里又涉及到两个注解
@AutoConfigurationPackage @Import(AutoConfigurationImportSelector.class)。
①:@AutoConfigurationPackage
自动配置包,指定了默认的包规则。

@AutoConfigurationPackage注解的源码:

使用@Import注解导入一个AutoConfigurationPackages.Registrar的类,使用@SpringBootApplication注解标识的类所在的包以及所在子包下的所有类,自动扫描注册到Spring容器中 。跟之前学习Spring时,使用的xml文件中,组件扫描基础包的功能一样。

复制代码
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import({AutoConfigurationPackages.Registrar.class})
public @interface AutoConfigurationPackage {
    
}

②:**Import(AutoConfigurationImportSelector.class)
AutoConfigurationlmportSelector是 Spring Boot中一个重要的类,它实现了ImportSelector接口, 核心使命是
按照特定规则筛选并导入符合条件的自动配置类**,让 Spring Boot 能 "自动" 完成大量配置工作,无需开发者手动编写 XML 或 Java 配置。

它的工作可以拆解为以下关键步骤,按执行顺序梳理:

  1. 加载自动配置类的候选列表
    1. 首先读取 Spring Boot 内置的 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件(Spring Boot 2.7+ 版本,旧版本是 spring.factories),这个文件里列出了所有内置的自动配置类(比如 DataSourceAutoConfiguration、WebMvcAutoConfiguration 等)。
    2. 这一步的核心是拿到所有候选自动配置类的全限定类名,是后续筛选的基础。
  2. 筛选符合条件的自动配置类
    这是最核心的工作,会根据以下规则过滤掉不需要的配置类:
    1.条件注解过滤 :检查自动配置类上的 @Conditional 系列注解(如 @ConditionalOnClass、
    @ConditionalOnMissingBean、@ConditionalOnProperty 等),只有满足条件的类才会被保留。
    例如:DataSourceAutoConfiguration 会检查类路径下是否有 JDBC 相关类,没有则跳过该配置。
    2.排除规则过滤
    排除用户通过 @SpringBootApplication(exclude = ...) 主动指定排除的配置类;排除通过配置项

spring.autoconfigure.exclude 指定的配置类;排除不符合当前环境的配置类(比如非 Web 环境排

除 Web 相关自动配置)
3.排序并导入最终的自动配置类:

对筛选后的自动配置类按优先级排序(比如通过 @AutoConfigureOrder、@Order 注解,或内置的排序规则),确保配置加载的顺序符合依赖逻辑(比如数据源配置要先于事务配置)。

把最终筛选、排序后的自动配置类全限定名返回给 Spring 容器,Spring 会将这些类作为配置类加载,完成 Bean 的自动注册。

4.辅助工作:处理配置元数据

加载自动配置类的元数据(比如配置项的说明、默认值、是否必填等),这些元数据会用于 IDE 提示、配置校验等场景,提升开发体验。

相关推荐
ss2732 小时前
ruoyi 新增每页分页条数
java·数据库·mybatis
悟能不能悟2 小时前
springboot怎么将事务设置为pending,等另外一个请求ok了,再做commit
spring boot·后端
benpaodeDD2 小时前
黑马SpringBoot2自动配置原理
java·spring boot·后端
编程大师哥2 小时前
Java web
java·开发语言·前端
电商API_180079052472 小时前
大麦网API实战指南:关键字搜索与详情数据获取全解析
java·大数据·前端·人工智能·spring·网络爬虫
dasi02272 小时前
Java 趣闻
java
C雨后彩虹2 小时前
synchronized高频考点模拟面试过程
java·面试·多线程·并发·lock
JAVA+C语言2 小时前
Java ThreadLocal 的原理
java·开发语言·python
lkbhua莱克瓦242 小时前
进阶-SQL优化
java·数据库·sql·mysql·oracle