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

【Spring Boot】自动装配机制详解

1. 传统的 Spring 注入方式(基于 XML 配置)

在传统的 Spring 中,依赖注入(DI)通常通过 XML 配置文件来进行管理。常见的方式有两种:

  • 通过 <property> 元素进行属性注入
  <bean id="car" class="com.example.Car"><property name="engine" ref="engine"/></bean>
  • 通过 <constructor-arg> 元素进行构造器注入
  <bean id="car" class="com.example.Car"><constructor-arg ref="engine"/></bean>

这些注入方式的核心思想是 控制反转(IoC),即 Spring 容器负责管理类的实例化和依赖关系的注入。

2. Spring Boot 中的自动装配机制

在 Spring Boot 中,自动装配机制通过 @Autowired 注解简化了开发过程,消除了 XML 配置的复杂性。以下是其基本的工作原理:

2.1 @Autowired 注解

@Autowired 注解可以用来自动装配 Bean。在 Spring Boot 中,容器会根据类型自动找到匹配的 Bean 并注入到指定字段、构造函数或方法中。

  • 字段注入
  @Autowiredprivate Car car;
  • 构造器注入(推荐的方式):
  private final Car car;@Autowiredpublic MyService(Car car) {this.car = car;}
2.2 自动配置的原理(@EnableAutoConfiguration

Spring Boot 的自动配置通过 @EnableAutoConfiguration 注解启动。这是一个非常重要的注解,负责启用 Spring Boot 的自动配置功能。背后涉及的几个关键步骤如下:

  • @EnableAutoConfiguration 注解会触发 AutoConfigurationImportSelector 类的加载,AutoConfigurationImportSelector 类的作用是根据条件筛选出需要自动配置的类。
  • AutoConfigurationImportSelector.selectImports() 方法负责从多个候选配置类中筛选出需要导入的类。最终这些类会被注册为 Spring 容器的 Bean。
2.3 自动配置类的加载过程

自动配置类的筛选和加载过程较为复杂,但可以总结为以下几个步骤:

  1. 加载候选配置类:通过 getCandidateConfigurations() 方法,Spring Boot 会加载出所有可能的自动配置类。
  2. META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 中读取配置:在 Spring Boot 启动时,会读取 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件中的内容,这个文件列出了所有的自动配置类的全类名。
  3. 将自动配置类注册为 Bean:这些自动配置类会被加载并注册为 Spring 上下文中的 Bean,从而实现自动装配。
2.4 @Component 注解与自动装配

在 Spring 中,可以通过 @Component 及其派生注解(如 @Controller@Service@Repository 等)来声明一个类为 Bean。Spring Boot 在启动时会扫描带有这些注解的类,并将其自动注册到 Spring 容器中。

@Component
public class MyBean {// Bean 的逻辑
}

这些 Bean 可以通过 @Autowired 注解自动注入到其他类中。

2.5 自动装配的条件控制(@Conditional)

Spring Boot 还提供了条件装配机制。使用 @Conditional 注解可以让开发者根据某些条件决定是否进行自动配置。例如,@ConditionalOnProperty 可以根据配置文件中的某些属性值来决定是否装配某个 Bean。

@Configuration
@ConditionalOnProperty(name = "my.feature.enabled", havingValue = "true")
public class MyAutoConfiguration {// 如果配置了 my.feature.enabled=true,则这个配置会生效
}

3. 总结

  • @Autowired 注解:通过注解自动注入 Bean,Spring Boot 会自动进行依赖注入,无需显式配置。
  • @EnableAutoConfiguration:这是 Spring Boot 实现自动配置的核心,负责自动配置 Bean 并将其注入到容器中。
  • 自动配置的加载机制:Spring Boot 通过 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件来加载自动配置类,并根据条件决定是否加载。
  • @Component 等注解:通过这些注解声明 Bean,Spring Boot 会自动进行类扫描并将其加入容器。

4.DI注入的理解

传统的Spring注入是通过Spring XML配置文件中的 <bean> 标签中的 <property> 进行设值注入,也可以通过 <constructor-arg> 进行构造器注入,这两种方式都是控制反转(IoC)的注入方式,即通过外部容器管理对象的依赖关系。

现在有了 @Autowired 注解后,想要注入对象,首先需要确定Bean对象。可以通过 @Component@Controller@Service@Repository 等注解来定义Bean对象。接着在需要注入的字段上添加 @Autowired 注解实现自动装配。

Spring会通过启动类上的 @SpringBootApplication 注解找到类内部的 @EnableAutoConfiguration 注解,这个注解负责自动装配。具体来说,@EnableAutoConfiguration 注解通过 @Import(AutoConfigurationImportSelector.class) 导入 AutoConfigurationImportSelector 类,该类负责筛选出需要自动配置的类。

AutoConfigurationImportSelector 类中有一个 selectImports 方法,该方法的作用是将筛选出来的类名对应的Bean对象注入到IOC容器中,实现自动装配。筛选的条件是通过一个配置文件来确定的。要找到这个配置文件,需要查看 selectImports 方法中的 autoConfigurationEntry,该方法通过 getAutoConfigurationEntry 实现。进一步跟踪 getAutoConfigurationEntry 方法,可以看到它返回一个 AutoConfigurationEntry 对象,其中有一个参数 configurations,这个 configurations 是由 getCandidateConfigurations 方法实现的。继续跟踪 getCandidateConfigurations 方法,可以看到返回值 configurations 是由 ImportCandidates.load 方法实现的,该方法的参数是 AutoConfiguration.class 配置类。

在报错信息中可以看出,这些配置类的全类名最终会存储在 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件中。因此,通过这一系列调用,Spring Boot会自动装配这些类,并将它们生成为相应的Bean对象。

Spring Boot 的自动装配大大简化了开发流程,避免了大量的配置工作,开发者只需关注业务逻辑即可。

相关文章:

【Spring Boot】自动装配机制详解

1. 传统的 Spring 注入方式&#xff08;基于 XML 配置&#xff09; 在传统的 Spring 中&#xff0c;依赖注入&#xff08;DI&#xff09;通常通过 XML 配置文件来进行管理。常见的方式有两种&#xff1a; 通过 <property> 元素进行属性注入&#xff1a; <bean id&qu…...

Flink集群搭建整合Yarn运行

Flink 集群 1. 服务器规划 服务器h1、h4、h5 2. StandAlone 模式&#xff08;不推荐&#xff09; 2.1 会话模式 在h1操作 #1、解压 tar -zxvf flink-1.19.1-bin-scala_2.12.tgz -C /app/#2、修改配置文件 cd /app/flink-1.19.1/conf vim conf.yaml ##内容&#xff1a;## j…...

Linux Ubuntu 安装配置RabbitMQ,springboot使用RabbitMQ

rabbit-Ubuntu 一篇文章学会RabbitMQ 在Ubuntu上查看RabbitMQ状态可以通过多种方式进行&#xff0c;包括使用命令行工具和Web管理界面。以下是一些常用的方法&#xff1a; 1-使用systemctl命令&#xff1a; sudo systemctl start rabbitmq-server sudo systemctl status ra…...

云数据库 MongoDB

MongoDB 是一个基于文档的 NoSQL 数据库&#xff0c;它与传统的关系型数据库不同&#xff0c;采用的是灵活的文档结构&#xff08;类似 JSON 格式&#xff09;。MongoDB 是开源的&#xff0c;且高度可扩展&#xff0c;通常用于处理大量的非结构化或半结构化数据。 云数据库 Mon…...

Ionic 8.4 简介

Ionic 是一个用于开发混合移动应用、渐进式Web应用&#xff08;PWA&#xff09;以及桌面应用的开源框架。它结合了 Angular、React 或 Vue.js 等现代前端框架与 Cordova/PhoneGap 的力量&#xff0c;允许开发者使用 Web 技术&#xff08;HTML, CSS, JavaScript&#xff09;构建…...

蓝桥杯系列---class1

&#x1f308;个人主页&#xff1a;羽晨同学 &#x1f4ab;个人格言:“成为自己未来的主人~” 我们今天会再开一个系列&#xff0c;那就是蓝桥杯系列&#xff0c;我们会从最基础的开始讲起&#xff0c;大家想要备战明年蓝桥杯的&#xff0c;让我们一起加油。 工具安装 DevC…...

vue3+elementPlus封装的一体表格

目录结构 源码 exportOptions.js export default reactive([{label: 导出本页,key: 1,},{label: 导出全部,key: 2,}, ])index.vue <template><div class"flex flex-justify-between flex-items-end"><div><el-button-group><slot name…...

Junit5 单元测试入门

基础知识 常用注解含义 Test&#xff1a;标记一个方法为测试方法BeforeEach&#xff1a;标记的方法会在每个测试方法执行前执行AfterEach&#xff1a;标记的方法会在每个测试方法执行后执行BeforeAll&#xff1a;标记的方法会在所有测试方法执行前执行一次AfterAll&#xff1…...

数字信号处理-数学基础

来源哪都有&#xff0c;个人复习使用 一 积分 常用积分公式&#xff1a; 基本积分方法 凑微分法(也称第一换元法)&#xff1a; 换元&#xff1a; 分部积分&#xff1a; 卷积 这里有动图解释&#xff1a; https://mathworld.wolfram.com/Convolution.html 欧拉公式 e i x…...

【Exp】# Microsoft Visual C++ Redistributable 各版本下载地址

Microsoft官方页面 https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads Redistributable 2019 X86: https://aka.ms/vs/16/release/VC_redist.x86.exe X64: https://aka.ms/vs/16/release/VC_redist.x64.exe Redistributable 201…...

Hive 分桶表的创建与填充操作详解

Hive 分桶表的创建与填充操作详解 在 Hive 数据处理中&#xff0c;分桶表是一个极具实用价值的功能&#xff0c;它相较于非分桶表能够实现更高效的采样&#xff0c;并且后续还可能支持诸如 Map 端连接等节省时间的操作。不过&#xff0c;值得注意的是&#xff0c;在向表写入数…...

[小白系列]Ubuntu安装教程-安装prometheus和Grafana

Docker安装prometheus 拉取镜像 docker pull prom/prometheus 配置文件prometheus.yml 在/data/prometheus/建立prometheus.yml配置文件。&#xff08;/data/prometheus/可根据自己需要调整&#xff09; global:scrape_interval: 15s # By default, scrape targets ev…...

Flask使用长连接

Flask使用flask_socketio实现websocket Python中的单例模式 在HTTP通信中&#xff0c;连接复用&#xff08;Connection Reuse&#xff09;是一个重要的概念&#xff0c;它允许客户端和服务器在同一个TCP连接上发送和接收多个HTTP请求/响应&#xff0c;而不是为每个新的请求/响…...

数据分析思维案例:游戏评分低,怎么办?

【面试题】 某款手游在应用市场评分相比同类型游戏处于劣势。 请分析可能的原因并给出相关建议。 【分析思路】 一、明确问题 1. 明确业务指标 定义&#xff1a;应用市场评分一般指某一应用在某个应用市场上线以来的总体平均评分。 除“总体平均评分”以外&#xff0c;部分应用…...

【学习总结|DAY012】Javabean书写练习

一、主要代码 public class Phone {public Phone() {}public Phone(String brand, int price, String color) {this.brand brand;this.price price;this.color color;}String brand;int price;String color;public String getBrand() {return brand;}public void setBrand(…...

Mac环境下brew安装LNMP

安装不同版本PHP 在Mac环境下同时运行多个版本的PHP&#xff0c;同Linux环境一样&#xff0c;都是将后台运行的php-fpm设置为不同的端口号&#xff0c;下面将已php7.2 和 php7.4为例 添加 tap 目的&#xff1a;homebrew仅保留最近的php版本&#xff0c;可能没有你需要的版本…...

openEuler 知:安装系统

文章目录 前言图形化安装文本方式安装 前言 本文只介绍安装过程中需要特别注意的地方&#xff0c;常规的内容需要参考其它文档。 图形化安装 自定义分区&#xff1a; 说明&#xff1a;anaconda 默认分区&#xff0c;在 OSNAME.conf 中进行了配置&#xff0c;openEuler 默认根…...

Zephyr 入门-设备树与设备驱动模型

学习链接&#xff1a;https://www.bilibili.com/video/BV1L94y1F7qS/?spm_id_from333.337.search-card.all.click&vd_source031c58084cf824f3b16987292f60ed3c 讲解清晰&#xff0c;逻辑清楚。 1. 设备树概述&#xff08;语法&#xff0c;如何配置硬件&#xff0c;c代码如…...

点云标注软件SUSTechPOINTS的安装和使用,自测win10和ubuntu20.04下都可以用

点云标注软件SUSTechPOINTS的安装和使用 github项目源码&#xff1a;https://github.com/naurril/SUSTechPOINTS gitee源码以及使用教程&#xff1a;https://gitee.com/cuge1995/SUSTechPOINTS 首先拉取源码 git clone https://github.com/naurril/SUSTechPOINTS最好是在cond…...

etcd资源超额

集群内apiserver一直重启&#xff0c;重启kubelet服务后查看日志发现一下报错&#xff1a; Error from server: etcdserver: mvcc: database space exceeded 报错原因&#xff1a; etcd服务未设置自动压缩参数&#xff08;auto-compact&#xff09; etcd 默认不会自动 compa…...

后进先出(LIFO)详解

LIFO 是 Last In, First Out 的缩写&#xff0c;中文译为后进先出。这是一种数据结构的工作原则&#xff0c;类似于一摞盘子或一叠书本&#xff1a; 最后放进去的元素最先出来 -想象往筒状容器里放盘子&#xff1a; &#xff08;1&#xff09;你放进的最后一个盘子&#xff08…...

在软件开发中正确使用MySQL日期时间类型的深度解析

在日常软件开发场景中&#xff0c;时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志&#xff0c;到供应链系统的物流节点时间戳&#xff0c;时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库&#xff0c;其日期时间类型的…...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件&#xff1a; 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

Oracle查询表空间大小

1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...

CentOS下的分布式内存计算Spark环境部署

一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架&#xff0c;相比 MapReduce 具有以下核心优势&#xff1a; 内存计算&#xff1a;数据可常驻内存&#xff0c;迭代计算性能提升 10-100 倍&#xff08;文档段落&#xff1a;3-79…...

《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》

在注意力分散、内容高度同质化的时代&#xff0c;情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现&#xff0c;消费者对内容的“有感”程度&#xff0c;正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中&#xff0…...

WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成

厌倦手动写WordPress文章&#xff1f;AI自动生成&#xff0c;效率提升10倍&#xff01; 支持多语言、自动配图、定时发布&#xff0c;让内容创作更轻松&#xff01; AI内容生成 → 不想每天写文章&#xff1f;AI一键生成高质量内容&#xff01;多语言支持 → 跨境电商必备&am…...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 在 GPU 上对图像执行 均值漂移滤波&#xff08;Mean Shift Filtering&#xff09;&#xff0c;用于图像分割或平滑处理。 该函数将输入图像中的…...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)

上一章用到了V2 的概念&#xff0c;其实 Fiori当中还有 V4&#xff0c;咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务)&#xff0c;代理中间件&#xff08;ui5-middleware-simpleproxy&#xff09;-CSDN博客…...

基于IDIG-GAN的小样本电机轴承故障诊断

目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) ​梯度归一化(Gradient Normalization)​​ (2) ​判别器梯度间隙正则化(Discriminator Gradient Gap Regularization)​​ (3) ​自注意力机制(Self-Attention)​​ 3. 完整损失函数 二…...