SpringBoot的自动配置原理!

文章目录

目录

前言

一、自动配置的含义是什么?

二、详细理解SpringBoot 的自动配置原理!!!

总结:自动配置的完整详细的简单流程

关键亮点:用户配置的优先级



前言

      什么是Spring Boot呢? Spring Boot 是 Pivotal 团队研究开发的一款基于 Spring 框架的开源 Java 开发框架,它的核心目标是简化 Spring 应用的初始搭建和开发过程。Spring Boot 多用于开发微服务、RESTful API、Web 应用等,是目前 Java 后端开发中非常流行的框架之一。它并不替代 Spring,而是对 Spring 框架的增强,让我们开发人员能够更专注于业务逻辑而非框架配置简单来说,Spring Boot 为开发者提供了一套 “开箱即用” 的解决方案,让开发者可以快速繁就简,快速构建独立运行的 Spring 应用。他有一个核心的特定就是::自动配置:自动配置就是根据项目中引入的依赖(如数据库驱动、Web 组件等),自动完成 Spring 相关配置,减少手动 XML 或注解配置的工作量。今天我们主要讲讲SpringBoot的自动配置原理!!

一、自动配置的含义是什么?

        在 Spring Boot 中,自动配置(Auto-configuration) 是它的核心特性之一,简单来说,它指的是:Spring Boot 会根据项目中引入的依赖(JAR 包)和配置信息,自动的推断并且配置应用需要的组件,不需要开发的人去手动编写大量 的XML 或者注解配置。

          说白了就是,你想开发个 Web 应用,就加个 Web 相关的依赖包;想连数据库,就加个数据库相关的依赖。Spring Boot 看到你加了这些包,就知道你想干嘛了,会自动帮你把各种需要的配置都弄好。不用你自己写一堆复杂的配置代码,它就像个贴心助手,根据你加的 "零件",自动把应用的基础框架搭好,你直接写业务逻辑就行。这莫说,就可以更好的理解了吧。

二、详细理解SpringBoot 的自动配置原理!!!

         我们用一句话概括核心逻辑:

          Spring Boot 启动时,会根据「你引入的依赖」和「你的配置」,自动往 Spring 容器里放一些预先写好的组件(Bean),省去你手动配置的麻烦

        对于我们初学Spring Boot的同学们来说,要理解 Spring Boot 的自动配置原理,我们可以把它拆解成「3 个核心步骤」。

        步骤 1:自动配置的「开关」—— @EnableAutoConfiguration

Spring Boot 的启动类上总有一个注解@SpringBootApplication,这个注解里藏着自动配置的总开关:@EnableAutoConfiguration这个注解非常重要!!点进项目的启动类,按住Ctrl 点击自动类的@SpringBootConfiguration 注解我们就可一看到如下所示。

     我们用红色箭头指向的就是: 自动配置的「开关」—— @EnableAutoConfiguration。@EnableAutoConfiguration的作用就是:告诉 Spring Boot「开启自动配置功能」,它会帮你自动往容器里加组件。接下来我们再去看看@EnableAutoConfiguration的底层究竟内涵什么乾坤呢。

同样,按住Ctrl 点进@EnableAutoConfiguration,

   那么这里的关键就是这一个注解::@Import(AutoConfigurationImportSelector.class),这个AutoConfigurationImportSelector(自动配置导入选择器)就是用来「挑选哪些组件需要被自动配置」的核心类。

        步骤 2:自动配置类从哪来?—— 我们来一起读取 spring.factories

     @AutoConfigurationImportSelector的核心作用是:从指定文件里读取「需要自动配置的类名单」,然后把这些类导入到 Spring 容器中。接下来让我们一起看看它的核心方法selectImports:::

public class AutoConfigurationImportSelector implements DeferredImportSelector {
    
    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        }
        // 1. 加载自动配置的元数据(里面包含所有候选的自动配置类)
        AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
            .loadMetadata(this.beanClassLoader);
        // 2. 获取需要导入的自动配置类列表
        AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(
            autoConfigurationMetadata, annotationMetadata);
        return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
    }
    
    // 关键:获取自动配置类列表
    protected AutoConfigurationEntry getAutoConfigurationEntry(...) {
        // ... 省略校验逻辑
        
        // 从spring.factories里获取所有候选的自动配置类
        List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
        // ... 省略去重、排除等逻辑
        
        return new AutoConfigurationEntry(configurations, exclusions);
    }
    
    // 从哪里获取候选配置类?
    protected List<String> getCandidateConfigurations(...) {
        // 这里的FACTORIES_RESOURCE_LOCATION就是"META-INF/spring.factories"
        return SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
                                                     getBeanClassLoader());
    }
}

简单说:AutoConfigurationImportSelector会去读取项目里所有META-INF/spring.factories文件,这些文件里列出了「可能需要自动配置的类」。

比如 Spring Boot 自带的spring-boot-autoconfigure包中,就有一个META-INF/spring.factories,里面藏着几百个自动配置类,例如:

# spring-boot-autoconfigure/META-INF/spring.factories 部分内容
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,\

这些配置类(如DataSourceAutoConfigurationRedisAutoConfiguration)就是 Spring Boot 预先写好的(自动配置模板)。

        步骤 3:自动配置类何时生效?—— 条件注解的判断

拿到spring.factories里的自动配置类后,Spring Boot 并不会全部加载,而是会通过「条件注解」判断:这个类是否应该生效。

举个最常见的例子:DataSourceAutoConfiguration(数据库连接池的自动配置类),它的源码就是这样的:

// 数据库连接池自动配置类
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class }) // 条件1:类路径上必须有DataSource和EmbeddedDatabaseType这两个类
@ConditionalOnMissingBean(type = "io.r2dbc.spi.ConnectionFactory") // 条件2:容器里不能有ConnectionFactory类型的Bean
@EnableConfigurationProperties(DataSourceProperties.class) // 关联配置文件的属性(如application.yml里的spring.datasource)
@Import({ DataSourcePoolMetadataProvidersConfiguration.class, DataSourceInitializationConfiguration.class })
public class DataSourceAutoConfiguration {
    
    // 内部类:配置Hikari连接池(默认用Hikari)
    @Configuration(proxyBeanMethods = false)
    @ConditionalOnClass(HikariDataSource.class) // 条件:类路径上有HikariDataSource
    @ConditionalOnMissingBean(DataSource.class) // 条件:容器里没有用户自定义的DataSource
    @ConditionalOnProperty(name = "spring.datasource.type", havingValue = "com.zaxxer.hikari.HikariDataSource", matchIfMissing = true)
    static class Hikari {
        @Bean
        HikariDataSource dataSource(DataSourceProperties properties) {
            // 根据配置文件的属性(如url、username、password)创建HikariDataSource
            HikariDataSource dataSource = createDataSource(properties, HikariDataSource.class);
            // ... 省略配置细节
            return dataSource;
        }
    }
    
    // 还有其他内部类:配置Tomcat连接池、Dbcp2连接池等(根据条件生效)
}

这里的核心是条件注解,比如:

  • @ConditionalOnClass(HikariDataSource.class):只有当项目依赖里有HikariDataSource这个类(通常引入spring-boot-starter-jdbc就会带),这个配置才生效。
  • @ConditionalOnMissingBean(DataSource.class):如果用户自己在代码里定义了DataSource类型的 Bean(比如自定义连接池),那么 Spring Boot 的默认配置就不生效(用户配置优先)。


总结:自动配置的完整详细的简单流程

  1. 启动触发@SpringBootApplication包含@EnableAutoConfiguration,开启自动配置。
  2. 加载候选配置类AutoConfigurationImportSelector读取所有META-INF/spring.factories,拿到可能需要自动配置的类名单。
  3. 条件判断生效:每个自动配置类通过@ConditionalXXX注解判断是否符合条件(比如是否有对应依赖、是否没有用户自定义 Bean 等)。
  4. 注入组件到容器:符合条件的配置类会往 Spring 容器里注入对应的 Bean(比如数据库连接池、Redis 客户端等),并根据application.yml里的配置参数动态调整。

关键亮点:用户配置的优先级

Spring Boot 的自动配置不是(一刀切),而是(用户说了算)。比如:

  • 如果你在application.yml里配置了spring.datasource.url=jdbc:mysql://xxx,自动配置类会读取这些参数来创建连接池。
  • 如果你自己写了一个@Bean方法定义了DataSource,那么@ConditionalOnMissingBean会让默认配置失效,用你的自定义 Bean。

这就是为什么说 Spring Boot「约定优于配置」—— 它有默认方案,但我们随时随地都可以用简单的方式覆盖它。

        最后的最后,我们用一句话来概括SpringBoot的自动配置原理:Spring Boot 启动时,通过 @EnableAutoConfiguration 触发,从 META-INF/spring.factories 中读取候选配置类,再根据类路径下的依赖和条件注解判断哪些配置类生效,最终自动往容器中注入相应组件,同时允许用户配置覆盖默认值。

        好了,今天依旧是深蹲不写BUG,今天的内容到此为止,我们一起加油!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值