Spring Boot的自动装配机制?(Spring Boot怎么完成自动装配的?)----面试常问

news/2024/9/19 15:09:27/ 标签: spring boot, 面试, 后端

  Spring Boot的自动装配机制?(Spring Boot怎么完成自动装配的?)

目录

一、概念版(重要)

二、实操版 

1. 依赖管理 (pom.xml导坐标)

2. 自动配置类

2.1 @SpringBootApplication 注解 

2.2 @EnableAutoConfiguration 

2.3 @Import({AutoConfigurationImportSelector.class})

2.3.1  条件注解(Conditional Annotations) 

2.4 META-INF/spring.factories 文件


一、概念版(重要

      答:自动装配,简单来说就是自动去把第三方组件的Bean转载到IOC容器中,不需要开发人员再去手写Bean相关的一个配置。在Spring Boot应用里面,只需要在启动类上加上@SpringBootApplication注解就可以去实现自动装配。@SpringBootApplication是一个复合注解,真正去实现自动配置的是@EnableAutoConfiguration注解。

       自动装配主要依靠三个核心的关键技术。

     第一个,引入Starter启动依赖组件的时候,这个组件里面必须要包含一个@Configuation配置类,而在这个配置类里面,我们要通过@Bean注解去声明需要装配到IOC容器里面的Bean对象。

       第二个,这个配置类是放在第三方jar包里面的,然后通过Spring Boot中约定优于配置的理念去把这个配置类的全路径放在Classpath:/META-INF/spring.factories文件里面。这样的话,Spring Boot就可以知道第三方jar包里面这个配置类的位置。这个步骤主要是用到了Spring里面的SpringFactoriesLoader来完成的。

       第三个,Spring Boot 获取到所有第三方 jar 包中声明的配置类以后,再通过Spring提供的ImportSelector这样一个接口,来实现对这些配置类的动态加载,从而去完成自动装配这样一个动作。

       在我看来,Spring Boot是约定优于配置这一理念下的一个产物。所以在很多地方,都会看到这一类的思想,它的出现可以让开发人员更加聚焦的在业务代码的编写上,而不需要去关心和业务无关的配置。其实,自动装配的思想在SpringFramework 3.x版本里面的@Enable注解就已经有了实现的一个雏形。@Enable注解是一个模块驱动的意思,也就是说我们只需要增加@Enable注解就能自动打开某个功能,而不需要针对这个功能去做Bean的配置。@Enable注解的底层也是去帮我们自动完成这样一个模块相关Bean的注入的。

       以上就是我对Spring Boot的自动装配的一个理解。

注:约定优于配置理念是什么?

 约定优于配置(Convention Over Configuration) 是一种软件开发理念,指在软件开发中,遵循一些既定的约定和默认规则,从而减少开发人员需要进行的显式配置。

例如,在某些框架或技术中,可能会有以下的约定:

  • 项目的目录结构:按照特定的层次结构存放代码、配置文件、资源文件等。
  • 类和方法的命名规则:遵循一定的命名规范,以便框架能够自动识别和处理。
  • 配置文件的默认位置和格式:框架会默认在特定的位置查找具有特定格式的配置文件。

        通过遵循这些约定,开发人员无需花费大量时间和精力来详细配置每个细节,提高了开发效率,减少了配置错误的可能性,同时也使得代码和项目结构更加规范和易于理解。

        以 Spring Boot 为例,如果遵循了其约定,比如将应用的配置文件命名为 application.properties 或 application.yml 并放在特定的位置,框架就能自动识别并加载相应的配置,而无需开发人员显式地告诉框架配置文件的位置和名称。

二、实操版 

        Spring Boot 的自动配置(Auto-configuration)是其核心特性之一,它极大地简化了基于 Spring 的应用开发。  自动配置的工作原理主要依赖于“条件注解”(如 @Conditional)和 Spring Factories(META-INF/spring.factories 文件)

        以下是 Spring Boot 自动配置的基本步骤和原理:

1. 依赖管理 (pom.xml导坐标)

        首先,需要添加spring-boot-starter-web 依赖,Spring Boot 就会自动配置 Tomcat 和 Spring MVC。

# pom.xml<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>

        其次,在配置文件中写下Redis的配置就可以调用Redis的服务 

 

2. 自动配置类

自动配置类通常使用 @Configuration 注解进行标注。在配置类中,可以通过 @Bean 方法定义要注入到 IOC 容器中的 Bean 对象。 

例如:

2.1 @SpringBootApplication 注解 

首先进入@SpringBootApplication注解的源代码:

@SpringBootApplication 是一个在 Spring Boot 项目中常用的复合注解。

它组合了以下三个主要的注解功能:

  1. @SpringBootConfiguration表明这是一个 Spring Boot 的配置类,继承自 @Configuration ,用于定义 Bean 和配置相关的逻辑。

  2. @EnableAutoConfiguration开启 Spring Boot 的自动配置功能。它会根据项目所依赖的库和配置来自动配置应用程序所需的各种组件和设置。

  3. @ComponentScan:用于扫描和注册项目中的组件(例如 @Component 、@Service 、@Repository 等注解标注的类),使其能够被 Spring 容器管理。

总的来说,使用 @SpringBootApplication 注解可以简化 Spring Boot 项目的配置,使开发更加便捷高效。通常将其添加在项目的主启动类上

例如:自动配置类

package com.apesource.springbootstarter04;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import redis.clients.jedis.Jedis;@SpringBootApplication
public class SpringbootStarter04Application {public static void main(String[] args) {ConfigurableApplicationContext context =  SpringApplication.run(SpringbootStarter04Application.class, args);Jedis bean1 = context.getBean(Jedis.class);System.out.println(bean1);}}

 

2.2 @EnableAutoConfiguration 

 其次进入@EnableAutoConfiguration注解的源代码:

        在Spring Boot 项目的主启动类上,通常会添加@SpringBootApplication 注解。这是一个复合注解,其中关键的是 @EnableAutoConfiguration 注解,它开启了自动配置的功能。主要组合应用以下两个注解:

  1. @AutoConfigurationPackage,将项目src中main包下的所有组件注册到容器中,例如标注了Component注解的类等等

  2. @Import({AutoConfigurationImportSelector.class}),是自动装配的核心。 注解用于向 Spring 容器中导入指定的组件或配置类。

2.3 @Import({AutoConfigurationImportSelector.class})

选取部分 AutoConfigurationImportSelector类源代码

AutoConfigurationImportSelector 是 Spring Boot 中一个重要的类,它实现了ImportSelector接口,用于实现自动配置的选择和导入。具体来说,它通过分析项目的类路径和条件来决定应该导入哪些自动配置类。主要工作是:

  1. 扫描类路径: 在应用程序启动时,AutoConfigurationImportSelector 会扫描类路径上的 META-INF/spring.factories 文件,这个文件中包含了各种 Spring 配置和扩展的定义。在这里,它会查找所有实现了 AutoConfiguration 接口的类,具体的实现为getCandidateConfigurations方法。
  2. 条件判断: 对于每一个发现的自动配置类,AutoConfigurationImportSelector 会使用条件判断机制(通常是通过 @ConditionalOnXxx 注解)来确定是否满足导入条件。这些条件可以是配置属性、类是否存在、Bean是否存在等等。
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {// ... (其他方法和属性)// 获取所有符合条件的类的全限定类名,例如RedisTemplate的全限定类名(org.springframework.data.redis.core.RedisTemplate;),这些类需要被加载到 IoC 容器中。@Overridepublic String[] selectImports(AnnotationMetadata annotationMetadata) {// 扫描类路径上的 META-INF/spring.factories 文件,获取所有实现了 AutoConfiguration 接口的自动配置类List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);// 过滤掉不满足条件的自动配置类,比如一些自动装配类configurations = filter(configurations, annotationMetadata, attributes);// 排序自动配置类,根据 @AutoConfigureOrder 和 @AutoConfigureAfter/@AutoConfigureBefore 注解指定的顺序sort(configurations, annotationMetadata, attributes);// 将满足条件的自动配置类的类名数组返回,这些类将被导入到应用程序上下文中return StringUtils.toStringArray(configurations);}// ... (其他方法)protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {// 获取自动配置类的候选列表,从 META-INF/spring.factories 文件中读取// 通过类加载器加载所有候选类List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),getBeanClassLoader());// 过滤出实现了 AutoConfiguration 接口的自动配置类configurations = configurations.stream().filter(this::isEnabled).collect(Collectors.toList());// 对于 Spring Boot 1.x 版本,还需要添加 spring-boot-autoconfigure 包中的自动配置类// configurations.addAll(getAutoConfigEntry(getAutoConfigurationEntry(metadata)));return configurations;}// ... (其他方法)protected List<String> filter(List<String> configurations, AnnotationMetadata metadata,AnnotationAttributes attributes) {// 使用条件判断机制,过滤掉不满足条件的自动配置类configurations = configurations.stream().filter(configuration -> isConfigurationCandidate(configuration, metadata, attributes)).collect(Collectors.toList());return configurations;}// ... (其他方法)protected void sort(List<String> configurations, AnnotationMetadata metadata,AnnotationAttributes attributes) {// 根据 @AutoConfigureOrder 和 @AutoConfigureAfter/@AutoConfigureBefore 注解指定的顺序对自动配置类进行排序configurations.sort((o1, o2) -> {int i1 = getAutoConfigurationOrder(o1, metadata, attributes);int i2 = getAutoConfigurationOrder(o2, metadata, attributes);return Integer.compare(i1, i2);});}// ... (其他方法)}
2.3.1  条件注解(Conditional Annotations) 


Spring Boot 使用了一系列条件注解来决定是否应用特定的配置。例如:

  • @ConditionalOnClass:只有当指定的类在类路径中存在时,才会激活相关配置。
  • @ConditionalOnProperty:根据配置文件中的属性值来决定是否应用配置。

 例如:自定义主配置文件中RedisProperties文件必须存在才能执行

package com.apesource;import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.Jedis;
@Configuration
@EnableConfigurationProperties(RedisProperties.class)
public class RedisAutoconfiguration {@Beanpublic Jedis jedis(RedisProperties redisProperties){return new Jedis(redisProperties.getHost(),redisProperties.getPort());}
}

2.4 META-INF/spring.factories 文件

Spring Boot 会扫描项目及依赖的 JAR 包中的 META-INF\spring.factories文件。这个文件中定义了自动配置类的全限定名,Spring Boot 可以根据这些信息找到并加载相应的配置类。

  例如:resources\META-INF\spring.factories

# META-INF\spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\com.apesource.RedisAutoconfiguration

        总的来说,Spring Boot 的自动装配机制通过依赖管理、注解、条件判断、配置类扫描和注册等一系列操作,实现了根据项目的具体情况自动完成组件的配置和加载。


http://www.ppmy.cn/news/1511893.html

相关文章

旅游网站

TOC springboot281旅游网站 第1章 绪论 1.1 课题背景 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。所以各行业&#xff0…

【自用13.1】C++推箱子游戏

以下是初版代码&#xff0c;进行了初步的简单优化&#xff0c;具体思路以及优化步骤已经在备注中标明。 后期根据情况会出详细版的讲解。 #include <graphics.h> #include <iostream> #include <stdlib.h> #include <string> #include <conio.h&g…

Axios vs Fetch:哪种网络请求工具在 Vue 项目中更胜一筹?

在 Vue.js 项目中进行网络请求是开发过程中不可避免的一部分&#xff0c;而常用的两种工具就是 axios 和原生的 fetch。这两者各有优劣&#xff0c;开发者在选择时需要根据具体需求进行权衡。本文将详细对比 axios 和 fetch&#xff0c;并展示如何在 Vue 项目中封装和使用它们。…

ubuntu查看CPU、内存、硬盘

1、查看CPU cat /proc/cpuinfo 我这台机器CPU是2核&#xff0c;所以这里是2核 或者使用如下命令也可以查看 lscpu 查看CPU使用率 top 2、查看内存 查看内存信息&#xff1a; free -h 查看内存使用情况&#xff1a; vmstat 3、硬盘 查看硬盘使用情况&#xff1a; df -…

FPGA进阶教程15 使用mdio接口定义百兆以太网

我们接上一讲&#xff0c;要搞懂这一节的内容需要仔细分析一下mdio_ctrl的代码&#xff0c;在百兆以太网中&#xff0c;我们使用的YT8511芯片是需要关闭自协商模式的&#xff0c;也就是寄存器地址为0X00的第12位要置为0&#xff0c;寄存器定义如下图所示&#xff1a; 其次&…

选择金赛增,孩子轻松长高的科学方案

最初我意识到孩子身高矮的时候&#xff0c;其实走了很多弯路&#xff0c;什么钙铁锌硒&#xff0c;各种营养品没少吃&#xff0c;可能是心里不愿意面对孩子可能是生病了这件事&#xff0c;还试了很多偏方&#xff0c;最后实在是不见长&#xff0c;才去了医院。 一开始去市医院…

异构数据同步 datax (3) xxl-job 分布式任务调度

datax 需要手动执行 python 脚本来满足需求&#xff0c;可通过XXL-JOB 进行任务调度实现&#xff0c;满足自动化数据同步需求。 1、nacos 配置 # 配置 xxxx:job:runScript: /home/midware/datax/script/mysql_ps_test.shpythonScriptPath: /home/midware/datax/bin/datax.py j…

MiniCPM-V: A GPT-4V Level MLLM on Your Phone论文阅读

大模型的趋势&#xff1a;模型性能越来越好&#xff0c;模型参数变小&#xff0c;端边设备计算能力变强。 MiniCPM-V优点 结果好、OCR能力突出、多分辨率、多语言、易于部署 模型结构 图片encoder适用vit。输入整体以及切片。切片使用自适应算法&#xff0c;通过计算分数&am…

linux shell 脚本 let 数学计算

linux shell 脚本 let 数学计算 http://www.codebaoku.com/it-shell/ let命令中的算术表达式必须用双引号括起来&#xff0c;以避免解释器对特殊字符进行处理。 在变量的计算中&#xff0c;不需要使用$符号来表示变量&#xff0c; #!/bin/shweek_daydate %u echo $week_day…

MCU复位RAM会保持吗,如何实现复位时变量数据保持

在使用MCU时&#xff0c;通常大家默认MCU复位时RAM会被复位清零&#xff0c;那实际MCU复位时RAM是什么状态&#xff1f;如何让mcu复位时RAM保持不变呢&#xff1f; MCU复位有电源复位、Standby复位、内核复位、看门狗复位、引脚复位等。 其中内部会有掉电动作的复位有电源复位…

笔试练习day5

目录 游游的you题目解析解法方法一贪心方法二 腐烂的苹果题目解析例子1例子2解法多源BFS最短路径代码代码解析 JZ62 孩子们的游戏(圆圈中最后剩下的数)题目解析解法方法一模拟环形链表模拟数组模拟 方法二递推/递归/动态规划状态表示状态转移方程代码 感谢各位大佬对我的支持,如…

全新分支版本!微软推出Windows 11 Canary Build 27686版

已经很久没有看到 Windows 11 全新的分支版本了&#xff0c;今天微软发布 Windows 11 Canary 新版本&#xff0c;此次版本号已经转移到 Build 27xxx&#xff0c;首发版本为 Build 27686 版。 此次更新带来了多项改进&#xff0c;包括 Windows Sandbox 沙盒功能切换到 Microsof…

Compose(5)组件

讲一下compose的组件 在 Jetpack Compose 中&#xff0c;有许多不同类型的组件可用于构建用户界面。 一、基础组件 1.Text&#xff1a;用于显示文本内容。可以设置字体大小、颜色、样式等属性。 例如&#xff1a; Composablefun TextExample() {Text(text "Hello, Co…

【CAN-IDPS】汽车网关信息安全要求以及实验方法

《汽车网关信息安全技术要求及试验方法》是中国的一项国家标准,编号为GB/T 40857-2021,于2021年10月11日发布,并从2022年5月1日起开始实施 。这项标准由全国汽车标准化技术委员会(TC114)归口,智能网联汽车分会(TC114SC34)执行,主管部门为工业和信息化部。 该标准主要…

歌曲爬虫下载

本次编写一个程序要爬取歌曲音乐榜https://www.onenzb.com/ 里面歌曲。有帮到铁子的可以收藏和关注起来&#xff01;&#xff01;&#xff01;废话不多说直接上代码。 1 必要的包 import requests from lxml import html,etree from bs4 import BeautifulSoup import re impo…

【人工智能】使用NLP进行语音到文本的转换和主题的提取项目实践及案例分析一

一、项目概述 本项目旨在构建一个完整的语音到文本转换系统&#xff0c;并进一步从转换后的文本中提取主题。这涉及到自然语言处理&#xff08;NLP&#xff09;的多个关键技术&#xff0c;包括语音识别&#xff08;ASR, Automatic Speech Recognition&#xff09;、文本处理、…

【算法】马踏棋盘(骑士周游)问题回溯算法实现以及使用贪心算法优化

目录 1.游戏规则 2.算法分析 3.解决步骤和思路 4.马踏棋盘算法的代码实现 4.1计算马儿还能走哪些位置 4.2马踏棋盘的核心代码 4.3马踏棋盘算法完整代码 4.4使用贪心算法进行优化 4.4.1思路 4.4.2代码实现 1.游戏规则 将马儿随机放在国际象棋的 8*8 棋盘的某个方格中…

Java OkHttp使用(二)

文章目录 引言使用 OkHttp 发送回调其他 引言 记录一下 OkHttp 的使用&#xff1b;OkHttp 异步发送回调请求&#xff0c;增加回调失败重试。 使用 OkHttp 发送回调 /*** 回调重试类*/ Data public class CallBackRetryData {/*** 回调信息JSON*/private JSONObject bodyRequ…

设计模式反模式及UML图示常见误用案例分析

设计模式反模式及UML图示常见误用案例分析是一个深入探讨软件设计过程中常见问题及其解决方案的重要话题。在软件设计中&#xff0c;设计模式是用来解决常见问题的最佳实践&#xff0c;然而&#xff0c;当设计模式被错误地应用或误解时&#xff0c;就可能导致反模式的出现&…

edge浏览器可以,chrome浏览器看不到接口数据

chrome 谷歌浏览器&#xff0c;可以看到页面&#xff0c;F12的开发者工具看不到返回数据 无法加载响应数据: No data found for resource with given identifier Chrome 将显示 ERR_INTERNET_DISCONNECTED 错误 edge浏览器是正常的。 哈哈哈哈哈哈&#xff0c;这里误点了&a…