SpringBoot 自动装配原理及源码解析

目录

一、引言

二、自动装配原理

三、核心注解解析

[1、 @SpringBootApplication 注解](#1、 @SpringBootApplication 注解)

​编辑(1)@SpringbootConfiguration

(2)@ComponentScan

(3)@EnableAutoConfiguration

2、条件装配(Conditional系列注解)


一、引言

springboot 的自动装配(Auto-Configuration)是一种特性,它可以基于类路径上的条件以及属性文件中的设置自动配置 Spring 应用程序,简化开发人员需要编写的配置代码。

详情可以查阅:springboot参考指南

二、自动装配原理

自动装配实际上就是把第三方组件的Bean装载到IOC容器里,不需要开发人员再去写Bean相关的一个配置

三、核心注解解析

1、 @SpringBootApplication注解

通常只需要在SpringBoot应用启动类上加上 @SpringBootApplication 注解,就可以去实现自动装配。

@SpringBootApplication注解是一个复合注解,其主要包含三个重要的注解,@SpringBootConfiguration,@EnableAutoConfiguration和@ComponentScan

真正去实现自动装配的注解其实是 @EnableAutoConfiguration 注解。

(1)@SpringbootConfiguration

@SpringBootConfiguration 本质上就是 @Configuration,用于指定一个类是配置类。

(2)@ComponentScan

注解默认会扫描启动类所在的包下所有的类 ,为后续装配工作提供资源支持(也可以自定义不扫描某些包下的类)。

(3)@EnableAutoConfiguration

@EnableAutoConfiguration是自动配置的核心,它引导自动配置机制。

通过 @Import(AutoConfigurationImportSelector.calss)来引入AutoConfigurationImportSelector

AutoConfigurationImportSelector的作用是根据项目的依赖和配置情况,动态地选择并加载适合的自动配置类。

AutoConfigurationImportSelector的继承关系如下:

AutoConfigurationImportSelector 类通过重写实现了 ImportSelector接口中的selectImports方法,该方法主要用于获取所有符合条件的类的全限定类名,这些类需要被加载到 IOC容器 中。

java 复制代码
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!this.isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        } else {
            AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(annotationMetadata);
            return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
        }
    }

ImportSelector 接口用于实现动态地选择需要被导入到容器中的配置类的逻辑

java 复制代码
public interface ImportSelector {
    /**
     * @param importingClassMetadata 用于描述使用了 @Import 注解的配置类的注解元数据。
     * @return 数组中的每个元素都是一个全限定类名,表示需要被导入到容器中的配置类。
     */ 
    String[] selectImports(AnnotationMetadata var1);
    /**
     * 提供一个可选的排除过滤器,决定哪些配置类应该被排除在外。
     * 默认返回 null,表示没有排除过滤器。
     */
    @Nullable
    default Predicate<String> getExclusionFilter() {
        return null; // 默认没有排除过滤器
    }
}

getAutoConfigurationEntry方法通过一系列步骤,包括检查自动配置是否启用、获取候选配置、去除重复项、获取排除配置、检查排除的类是否有效、移除排除项、过滤配置,最终生成一个包含自动配置类和排除配置类的AutoConfigurationEntry对象。

getAutoConfigurationEntry方法是Spring Boot自动配置功能的核心,它确保了只有符合条件的自动配置类被加载到Spring应用上下文中。

java 复制代码
protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
    // 如果自动配置未启用,则返回空的自动配置条目
    if (!this.isEnabled(annotationMetadata)) {
        return EMPTY_ENTRY;
    } else {
        // 获取注解的属性
        AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
        // 获取候选的自动配置类
        List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
        // 移除重复的自动配置类
        configurations = this.removeDuplicates(configurations);
        // 获取需要排除的自动配置类
        Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);
        // 检查排除的类是否在候选配置类中
        this.checkExcludedClasses(configurations, exclusions);
        // 从候选配置类中移除排除的类
        configurations.removeAll(exclusions);
        // 使用配置类过滤器过滤自动配置类
        configurations = this.getConfigurationClassFilter().filter(configurations);
        // 触发自动配置导入事件
        this.fireAutoConfigurationImportEvents(configurations, exclusions);
        // 返回自动配置条目
        return new AutoConfigurationImportSelector.AutoConfigurationEntry(configurations, exclusions);
    }
}

接下来,我们debug看一下具体各个步骤内容:

1、判断自动装配开关是否打开,默认是spring.boot.enableautoconfiguration=true,可以在application.properties或者application.yml中设置开启或关闭。

2、获取EnableAutoConfiguration注解中的exclude 和excluedeName

3、获取需要自动装配的所有配置类,读取META-INF/spring.factories

4、在spring boot中,spring.factories文件中列出了许多自动配置类,但是这并不意味着每次应用启动时所有这些配置都会被加载。Spring Boot采用了一种称为条件配置的机制,使得只有在特定条件满足时,相关的自动配置类才会被激活和加载。

我们继续进行debug

可以发现,configurations的size值变小了,意味着并不是所有的配置都被加载了进去。

2、条件装配(Conditional系列注解)

Spring Boot在进行自动装配时并不是会盲目的把所有类全部装配进去,而是会有选择的进行,通过@Conditional系列注解来实现选择,常见条件包括:

@ConditionalOnClass:当类路径中存在某个类时才生效。
@ConditionalOnMissingBean:当 Spring 上下文中不存在某个 Bean 时才生效。
@ConditionalOnProperty:当某个配置属性满足特定条件时才生效。
@ConditionalOnBean:当 Spring 上下文中存在某个 Bean 时才生效。

@Conditional派生注解(Spring注解版原生的@Conditional作用)

作用:必须是@Conditional指定的条件成立,才给容器中添加组件,配置里面的所有内容才生效;

参考来源:SpringBoot 自动装配原理源码分析-CSDN博客

相关推荐
杨荧21 分钟前
【开源免费】基于Vue和SpringBoot的林业产品推荐系统(附论文)
前端·javascript·vue.js·spring boot·开源
xiao--xin26 分钟前
LeetCode100之搜索二维矩阵(46)--Java
java·算法·leetcode·二分查找
end_SJ36 分钟前
c语言 --- 字符串
java·c语言·算法
zzyh12345639 分钟前
spring cloud 负载均衡策略
java·spring cloud·负载均衡
涔溪40 分钟前
JS二叉树是什么?二叉树的特性
java·javascript·数据结构
zzyh1234561 小时前
springcloud负载均衡原理
java·spring cloud·负载均衡
东北赵四1 小时前
JVM之垃圾回收器G1概述的详细解析
java·开发语言·jvm
2403_875180952 小时前
一键掌握多平台短视频矩阵营销/源码部署
java·前端·数据结构·线性代数·矩阵·php
向阳12182 小时前
doris:手动分区
java·服务器·windows·doris
uzong2 小时前
新公司在使用的 Hibernate Validator 框架
java·后端