首页 > 编程语言 >【Java后端】SpringBoot 自动配置原理解析

【Java后端】SpringBoot 自动配置原理解析

时间:2024-10-18 18:19:26浏览次数:7  
标签:Conditional Java SpringBoot 后端 Spring 配置 bean 自动 注解

为什么就这一个注解,就可以让Spring Boot自动配置呢?

为了更清晰地阐述 Spring Boot 自动配置的底层原理,我们将结合源码进行更深入的分析,并加入一些关键步骤的代码片段。 

注意:按住Ctrl键不松,点击相应注解,即可进入对应源码

1. @SpringBootApplication 注解的秘密:开启自动配置之旅

进入 @SpringBootApplication 注解:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration //  标明配置类
@EnableAutoConfiguration // 启用自动配置
@ComponentScan // 组件扫描
public @interface SpringBootApplication {
    // ...
}

@SpringBootApplication 注解是 Spring Boot 的核心注解,它整合了三个关键注解:

  • @SpringBootConfiguration:声明该类为配置类,等同于 @Configuration。

  • @EnableAutoConfiguration:启用 Spring Boot 的自动配置机制。

  • @ComponentScan:启用组件扫描,自动发现和注册 Bean。

2. @EnableAutoConfiguration 深入剖析:AutoConfigurationImportSelector 的工作流程

@EnableAutoConfiguration 注解通过 @Import 注解导入 AutoConfigurationImportSelector:

@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
    // ...
}

如下图: 


 

AutoConfigurationImportSelector 实现了 ImportSelector 接口,其 selectImports() 方法是自动配置的核心逻辑:

public String[] selectImports(AnnotationMetadata importingClassMetadata) {
    AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
            .loadMetadata(this.beanClassLoader);
    AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(autoConfigurationMetadata,
            importingClassMetadata);
    return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}

如下图:

selectImports() 方法主要完成以下步骤:

  1. 加载自动配置元数据: AutoConfigurationMetadataLoader.loadMetadata() 从 META-INF/spring-autoconfigure-metadata.properties 文件中加载自动配置元数据,用于优化自动配置的性能,例如基于条件评估的缓存。

  2. 获取自动配置入口: getAutoConfigurationEntry() 方法是核心逻辑所在,它负责获取所有候选的自动配置类。

    private AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata,
            AnnotationMetadata importingClassMetadata) {
        if (!isEnabled(importingClassMetadata)) {
            return EMPTY_ENTRY;
        }
        AnnotationAttributes attributes = EnableAutoConfiguration.get(importingClassMetadata);
        List<String> exclusions = getExclusions(importingClassMetadata, attributes);
        Set<String> configurations = getCandidateConfigurations(importingClassMetadata, attributes);
        configurations.removeAll(exclusions);
        configurations = filter(configurations, autoConfigurationMetadata);
        fireAutoConfigurationImportEvents(configurations, exclusions);
        return new AutoConfigurationEntry(configurations, exclusions);
    }

  • getCandidateConfigurations():通过 SpringFactoriesLoader.loadFactoryNames() 从 META-INF/spring.factories 文件中加载所有自动配置类名称。
  • getExclusions():获取用户通过 exclude 属性或 excludeClass 属性排除的自动配置类。
  • filter():根据 @Conditional 注解进行过滤,只保留符合条件的自动配置类. 其中会利用 ConditionEvaluator 来评估每个 @Conditional 注解。
  • 最终返回 AutoConfigurationEntry 对象,其中包含了所有符合条件的自动配置类名称。

3. spring.factories 文件:自动配置类的清单

META-INF/spring.factories 文件中定义了 key 为 org.springframework.boot.autoconfigure.EnableAutoConfiguration 的配置项,其 value 为一系列自动配置类的全限定名。

4. @Conditional 注解:精细化自动配置

4.1 问题:在META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件中定义的配置类非常多,而且每个配置类中又可以定义很多的bean,那这些bean都会注册到Spring的IOC容器中吗?

答:并不是。 在声明bean对象时,上面有加一个以@Conditional开头的注解,这种注解的作用就是按照条件进行装配,只有满足条件之后,才会将bean注册到Spring的IOC容器中(下面会详细来讲解)

@Conditional 注解及其派生注解是 Spring Boot 自动配置的核心机制,用于根据各种条件判断是否加载某个自动配置类。

4.2 @Conditional

我们在跟踪SpringBoot自动配置的源码的时候,在自动配置类声明bean的时候,除了在方法上加了一个@Bean注解以外,还会经常用到一个注解,就是以Conditional开头的这一类的注解。以Conditional开头的这些注解都是条件装配的注解。下面我们就来介绍下条件装配注解。

@Conditional注解:

  • 作用:按照一定的条件进行判断,在满足给定条件后才会注册对应的bean对象到Spring的IOC容器中。

  • 位置:方法、类

  • @Conditional本身是一个父注解,派生出大量的子注解:

    • @ConditionalOnClass:判断环境中有对应字节码文件,才注册bean到IOC容器。

    • @ConditionalOnMissingBean:判断环境中没有对应的bean(类型或名称),才注册bean到IOC容器。

    • @ConditionalOnProperty:判断配置文件中有对应属性和值,才注册bean到IOC容器。

5. 自定义配置覆盖自动配置:控制加载顺序

@AutoConfigureBefore、@AutoConfigureAfter 和 @AutoConfigureOrder 注解可以控制自动配置类的加载顺序。

6. 自动配置源码小结

自动配置原理源码入口就是@SpringBootApplication注解,在这个注解中封装了3个注解,分别是:

  • @SpringBootConfiguration

    • 声明当前类是一个配置类

  • @ComponentScan

    • 进行组件扫描(SpringBoot中默认扫描的是启动类所在的当前包及其子包)

  • @EnableAutoConfiguration

    • 封装了@Import注解(Import注解中指定了一个ImportSelector接口的实现类)

      • 在实现类重写的selectImports()方法,读取当前项目下所有依赖jar包中META-INF/spring.factories、META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports两个文件里面定义的配置类(配置类中定义了@Bean注解标识的方法)。

当SpringBoot程序启动时,就会加载配置文件当中所定义的配置类,并将这些配置类信息(类的全限定名)封装到String类型的数组中,最终通过@Import注解将这些配置类全部加载到Spring的IOC容器中,交给IOC容器管理。

总结:自动配置流程再梳理

  1. @SpringBootApplication 启动自动配置流程。

  2. @EnableAutoConfiguration 导入 AutoConfigurationImportSelector。

  3. AutoConfigurationImportSelector 的 selectImports() 方法加载候选配置类。

  4. SpringFactoriesLoader 读取 META-INF/spring.factories 获取自动配置类列表。

  5. @Conditional 注解及其派生注解根据条件过滤配置类。

  6. 符合条件的自动配置类被加载,并注册 Bean 到 Spring 容器。

  7. 自定义配置可以覆盖自动配置。

总体步骤如下: 

通过深入源码,我们更清晰地理解了 Spring Boot 自动配置的原理和流程。 这有助于我们更好地利用 Spring Boot 的强大功能,并根据项目需求进行定制化配置。下期见,谢谢~

标签:Conditional,Java,SpringBoot,后端,Spring,配置,bean,自动,注解
From: https://blog.csdn.net/weixin_64178283/article/details/143058822

相关文章

  • java 11天 StringBuffer static
    补充:1--100正则表达式1-100 100拿出去或上“[1-9][0-9]{0,1}|100”0--100  0和100拿出去或上“[1-9][0-9]{0,1}|100|0”获取常量池中的地址 String - intern();String学过23个 一.StringBufferStringBuffer 字符串长度+16 StringBuffer空间是2*oldCap......
  • 基于SpringBoot框架的网上购书系统的设计与实现
    源码获取:点我!!!文章目录前言一、背景及意义选题背景选题目的二、系统设计主要功能运行环境三、系统实现部分页面截图展示部分代码展示前言提示:这里可以添加本文要记录的大概内容:二十一世纪是网络化,信息化的时代,为了满足广大读者的需求,设计并开发了适应于当前经......
  • Java工程师必备的20条SQL最佳实践详解
    在Java开发中,SQL是处理数据库交互的核心技能。高效的SQL查询不仅能够提升应用程序的性能,还能减少资源消耗和提高用户体验。以下是Java工程师必备的20条SQL最佳实践,每条都附有代码示例和详细解释。1.使用索引索引可以显著提高查询速度。为经常用于查询条件、排序和连接的......
  • SpringBoot+Vue+Uniapp私家车位共享小程序系统(源码+lw+部署文档+讲解等)
    项目运行截图技术框架后端采用SpringBoot框架SpringBoot是一个用于快速开发基于Spring框架的应用程序的开源框架。它采用约定大于配置的理念,提供了一套默认的配置,让开发者可以更专注于业务逻辑而不是配置文件。SpringBoot通过自动化配置和约定大于配置的......
  • 基于Java微信小程序的模拟考试系统(源码+lw+部署文档+讲解等)
    项目运行截图技术框架后端采用SpringBoot框架SpringBoot是一个用于快速开发基于Spring框架的应用程序的开源框架。它采用约定大于配置的理念,提供了一套默认的配置,让开发者可以更专注于业务逻辑而不是配置文件。SpringBoot通过自动化配置和约定大于......
  • java+vue计算机毕设高校图书馆借阅管理系统app【源码+程序+论文+开题】
    本系统(程序+源码)带文档lw万字以上文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景随着信息技术的飞速发展和移动互联网的普及,高校学生的学习和生活方式正经历着深刻的变革。图书馆作为知识传播和学术研究的重要场所,其管理与服务模式......
  • java+vue计算机毕设高校运动会管理系统【源码+程序+论文+开题】
    本系统(程序+源码)带文档lw万字以上文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景随着高校体育教育的不断发展,运动会作为增强学生体质、培养团队协作精神的重要活动,其组织与管理日益复杂。传统的人工管理方式存在效率低下、信息不透......
  • java+vue计算机毕设高校体育场馆管理【源码+程序+论文+开题】
    本系统(程序+源码)带文档lw万字以上文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景随着高等教育事业的蓬勃发展,高校体育场馆作为校园内重要的教学与生活设施,其管理效率与质量直接影响到师生的体育活动参与度及身心健康。近年来,高校体......
  • Java项目集成xxl-job(自动任务)
    官网|代码官网网址:https://www.xuxueli.com/xxl-job/首先:文档很详细,非常清晰,集成到项目中也非常简单进入官网后下拉就是文档按文档一步步一般没有问题,主要说下可能会疑惑的点直接点击1.5在gitee下载代码:http://gitee.com/xuxueli0323/xxl-job代码结构如下:以......
  • SpringBoot 2.3 升级到 SpringBoot 3.3 爬坑 -- HandlerInterceptorAdapter 拦截器无
    SpringBoot2.3升级到SpringBoot3.3爬坑SpringBoot2.3.0->spring-webmvc-5.2.6SpringBoot3.3.4->spring-webmvc-6.1.13HandlerInterceptorAdapter类在SpringFramework的较新版本中已经被废弃。在Spring6.1.13中,应使用HandlerInterceptor接口。HandlerInterc......