当前位置: 首页 > news >正文

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

目录

一、引言

二、什么是 Spring Boot 的自动装配

三、自动装配的核心注解解析

3.1 @SpringBootApplication 注解

(1)@SpringBootConfiguration:

(2)@EnableAutoConfiguration:

(3)@ComponentScan:

3.2 条件装配(@Conditional 系列注解)

示例:DataSourceAutoConfiguration

四、自动配置的工作流程

五、SpringBoot 自动装配的实际案例

六、好处


一、引言

        在 Java 开发领域,Spring Boot 占据着重要地位,其自动装配机制对传统开发模式产生了巨大变革。过去,传统 Spring 项目配置繁杂,极易出现版本冲突与配置错误,耗费开发者大量精力。而 Spring Boot 引入自动装配功能后,项目近乎可 “零配置” 启动,开发者能将主要精力集中于业务逻辑的实现,极大提高了开发效率。接下来,我们深入剖析 Spring Boot 自动装配背后的原理。

二、什么是 Spring Boot 的自动装配

        Spring Boot 自动装配是一套智能且高效的依赖注入与配置协调系统,遵循 “约定优于配置” 的原则。在项目启动阶段,它能够自动识别类路径下的各类组件及配置信息,并依据预先设定的精细规则完成装配任务。

三、自动装配的核心注解解析

3.1 @SpringBootApplication 注解

自动配置的起点通常是 @SpringBootApplication 注解,它是一个组合注解,包含了三个重要注解。

@SpringBootApplication
public class SpringBootDemo1031Application {public static void main(String[] args) {SpringApplication.run(SpringBootDemo1031Application.class, args);}
}

(1)@SpringBootConfiguration

本质等同于@Configuration,为自动装配的配置环节搭建基础框架,保障配置步骤有序进行

(2)@EnableAutoConfiguration

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";Class<?>[] exclude() default {};String[] excludeName() default {};
}

        它是是自动配置的核心,通过@Import(AutoConfigurationImportSelector.class)引入AutoConfigurationImportSelector。

AutoConfigurationImportSelector 类的继承体系如下:

public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware, ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {}public interface DeferredImportSelector extends ImportSelector {}public interface ImportSelector {String[] selectImports(AnnotationMetadata var1);
}

        可以看出,AutoConfigurationImportSelector类实现了ImportSelector接口,也就实现了这个接口中的selectImports方法,该方法主要用于获取所有符合条件的类的全限类名,这些类需要被加载到IOC容器中。 

public String[] selectImports(AnnotationMetadata annotationMetadata) {// 1.检查是否启用自动配置if (!this.isEnabled(annotationMetadata)) {return NO_IMPORTS;} else {// 2.获取所有需要装配的beanAutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(annotationMetadata);return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());}
}

getAutoConfigurationEntry方法通过一系列步骤,包括检查自动配置是否启用、获取候选配置、去除重复项、获取排除配置、检查排除的类是否有效、移除排除项、过滤配置,最终生成一个包含自动配置类和排除配置类的AutoConfigurationEntry对象。这个方法是Spring Boot自动配置功能的核心,它确保了只有符合条件的自动配置类被加载到Spring应用上下文中。

/*** 获取自动配置入口信息,包括需要加载的自动配置类和需要排除的配置类。** @param annotationMetadata 当前注解的元数据,提供了关于注解的信息,用于决定哪些自动配置类应该被导入。* @return 包含自动配置类和排除配置类的AutoConfigurationEntry对象。*/
protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {// 1. 如果自动配置没有被启用,则返回一个空的AutoConfigurationEntry对象if (!this.isEnabled(annotationMetadata)) {return EMPTY_ENTRY;} else {// 2. 从注解元数据中获取注解属性AnnotationAttributes attributes = this.getAttributes(annotationMetadata);// 3. 获取所有候选的自动配置类名List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);// 4. 去除候选配置中的重复项configurations = this.removeDuplicates(configurations);// 获取需要被排除的自动配置类名Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);// 检查排除的类是否在候选配置中,如果不在,则抛出异常this.checkExcludedClasses(configurations, exclusions);// 从候选配置中移除排除项configurations.removeAll(exclusions);// 使用ConfigurationClassFilter过滤候选配置configurations = this.getConfigurationClassFilter().filter(configurations);// 触发自动配置导入事件,通知所有监听器自动配置类即将被导入this.fireAutoConfigurationImportEvents(configurations, exclusions);// 创建并返回一个新的AutoConfigurationEntry对象,包含过滤后的配置和排除配置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 

自动配置类的信息通常位于spring-boot-autoconfigure模块的META-INF/spring.factories文件中。这个文件列出了所有可以被自动加载的配置类,当Spring Boot应用启动时,AutoConfigurationImportSelector会读取这个文件,并根据其中的信息将相应的自动配置类导入到应用上下文中。

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

(3)@ComponentScan

        负责搜索项目中的组件,收集散落的组件,为后续装配工作提供资源支持,确保所需组件无遗漏。

3.2 条件装配(@Conditional 系列注解)

Spring Boot并非盲目加载所有自动配置类,每个自动配置类通常都会运用@Conditional系列注解来实现有条件的加载,这极大地优化了资源配置,让自动装配更贴合项目实际需求。最常见的条件注解有:

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

示例:DataSourceAutoConfiguration

Spring Boot 中DataSourceAutoConfiguration 是配置数据源的自动配置类,它的源码如下:

@Configuration
@ConditionalOnClass(DataSource.class)
@EnableConfigurationProperties(DataSourceProperties.class)
@Import({DataSourcePoolMetadataProvidersConfiguration.class,DataSourceInitializationConfiguration.class})
public class DataSourceAutoConfiguration {@Bean@ConditionalOnMissingBeanpublic DataSource dataSource(DataSourceProperties properties) {return properties.initializeDataSourceBuilder().build();}
}
  • @ConditionalOnClass(DataSource.class):只有当类路径下存在 DataSource 类时,才进行数据源的自动配置。
  • @ConditionalOnMissingBean:如果 Spring 上下文中没有其他 DataSource Bean,则自动配置一个。

        只有当这些条件满足时,DataSourceAutoConfiguration才会被实例化和执行,这意味着Spring Boot在启动过程中,并不会盲目的加载spring.factories中的每一个自动配置类,而是基于运行环境和应用的配置智能选择激活配置。

四、自动配置的工作流程

1. 收集自动配置类

启动时,AutoConfigurationImportSelector 从 spring.factories 文件中读取所有的自动配置类,并通过 @Import 导入这些类。

2. 条件检查

自动配置类的加载不是无条件的,Spring Boot 会根据 @Conditional 注解进行条件检查,确保只有符合条件的自动配置类才会生效。

3. 注入所需的 Bean

一旦自动配置类通过条件检查,Spring Boot 就会根据这些配置类注册所需的 Bean。例如,DataSourceAutoConfiguration 会自动配置数据源相关的 Bean。

4. 允许用户覆盖自动配置

自动配置并不是强制的。用户可以通过显式声明自己的 Bean 来覆盖自动配置的默认行为。例如,如果用户在自己的配置类中定义了 DataSource,那么 Spring Boot 就不会再自动配置数据源。

五、SpringBoot 自动装配的实际案例

1. Web 应用自动配置

在 Spring Boot Web 应用中,DispatcherServletAutoConfiguration 负责自动配置 Spring MVC 的核心组件,例如 DispatcherServletRequestMappingHandlerMapping 等。

  • 如果项目中存在 spring-web 依赖,那么 DispatcherServletAutoConfiguration 会自动加载。
  • 如果没有手动定义 DispatcherServlet,Spring Boot 会自动创建一个 DispatcherServlet 并配置到 Spring 容器中。

2. 数据库连接池自动配置

Spring Boot 还会自动配置数据库连接池(如 HikariCP、Tomcat JDBC 等),这依赖于项目中的 spring-boot-starter-data-jpa 或者 spring-boot-starter-jdbc 依赖。

  • DataSourceAutoConfiguration 和 DataSourceProperties 共同负责自动配置数据源。
  • 如果类路径中存在连接池类(如 DruidDataSource),那么 Spring Boot 就会自动配置连接池。

六、好处

1. 提高开发效率

开发者摆脱繁琐配置工作,无需反复查阅文档、调试配置,节省大量时间,得以聚焦业务功能迭代,在市场竞争中抢占先机。

2. 降低学习成本

对于初涉 Spring 技术栈的新手,复杂的 Spring 配置体系曾令人望而却步。自动装配机制降低入门难度,使其无需陷入配置困境,轻松上手融入团队。

3. 保证一致性

自动装配由 Spring Boot 框架统一管理控制,遵循统一约定,不同项目结构与配置趋于一致,便于团队协作、代码维护与知识传承,保障项目生命周期稳健延续。

        总之,Spring Boot 自动装配机制为 Java 开发注入强大动力,深入理解其原理和流程,有助于开发者在开发领域游刃有余。后续可探索定制化自动装配,拓展框架应用边界,激发更多创新可能。

http://www.lryc.cn/news/508861.html

相关文章:

  • Craft CMS 模板注入导致 Rce漏洞复现(CVE-2024-56145)(附脚本)
  • Next.js 新手容易犯的错误 _ 加载与缓存管理的关键(5)
  • /etc/fstab 文件学习systemd与该文件关系
  • 从源码分析swift GCD_DispatchGroup
  • 25计软新增考研院校!或可捡漏上岸!
  • C# 线程安全集合
  • 箱包发霉怎么处理 箱包发霉处理修复方法
  • 【每日学点鸿蒙知识】Charles抓包、lock文件处理、WebView组件、NFC相关、CallMethod失败等
  • 【异常】GL-SFT1200路由器中继模式,TL-CPE1300D无法搜寻5G网问题分析
  • LINUX--shell
  • TCP常见问题
  • OpenCV学习——图像融合
  • 网速、续航双在线!2024随身WiFi品牌精选推荐!格行按键切三网值得买吗?
  • ubuntu18.04连接不上网络问题
  • 访谈积鼎科技总经理:国产CFD软件发展与未来趋势展望
  • 【Linux知识】exec命令行详解
  • 【学术小白的学习之路】基于情感词典的中文句子情感分析(代码词典获取在结尾)
  • Linux 中 grep、sed、awk 命令
  • 一起考高项啊--现代化基础设施(工业互联网)
  • python学opencv|读取图像(二十)使用cv2.circle()绘制圆形进阶
  • 期权懂|如何减小个股期权交易中的风险?
  • ubuntu20.04 wget下载--段错误 (核心已转储)
  • 怎么样保持mysql和redis数据一致性
  • 剑指Offer|LCR 013. 二维区域和检索 - 矩阵不可变
  • aosp15 - Activity生命周期切换
  • vxe-table 虚拟滚动的动态响应
  • quasar dev 命令卡住很久
  • 黑盒RCE测试 异或测试
  • kotlin中泛型中in和out的区别
  • c# iis 解决跨域问题