SpringBoot3自动配置原理

​​​​​​自动配置

遵循约定大约配置的原则,在boot程序启动后,起步依赖中的一些bean对象会自动注入到ioc容器

看一下我们前面写的代码有没有达到自动配置的效果呢?

没有自动,我们写了配置类,写了@Import注解,所以并没有达到自动配置的效果。那怎么办呢?接下来我们通过翻看源码的方式来了解一下SpringBoot自动配置是怎么回事!了解完毕之后我们照葫芦画瓢就可以解决问题!

自动配置-源码分析

程序引入spring-boot-starter-web 起步依赖,启动后,会自动往ioc容器中注入DispatcherServlet

接下来我们验证一下,看它有没有自动注入DispatcherServlet

创建一个SpringBoot工程

这里没有 web起步依赖

 <dependencies>
        <!--springboot核心起步依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

主启动

@SpringBootApplication
public class SpringbootAutoConfigApplication {
​
    public static void main(String[] args) {
        ApplicationContext context = SpringApplication.run(SpringbootAutoConfigApplication.class, args);
        System.out.println(context.getBean("dispatcherServlet"));
    }
}

这时候工程里面没有 web起步依赖 就没有 DispatcherServlet,这里就会报错

导入 web起步依赖

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

那就验证了之前的话,如果你引入了web起步依赖,就会自动往ioc容器中注入一个DispatcherServlet,那SpringBoot如何做到的呢?接下来就要翻一下源码了。

源码解读

@SpringBootApplication 注解

我们进入这个注解,它的头上怎么顶着这么多注解,不过真正重要的只有三个注解,我们接下来会 一 一介绍。

@Target(ElementType.TYPE)  //元注解,可以在类上面使用 @Retention(RetentionPolicy.RUNTIME) //元注解,运行时阶段

@Documented  //生成Java文档

@Inherited  //是一个标识,用来修饰注解

@SpringBootConfiguration 注解

点进@SpringBootConfiguration注解,可以发现其核心注解为@Configuration注解:

@Configuration注解是Spring框架的注解之一,用于标记配置类。 在Spring Boot中,使用@Configuration注解可以将该类作为配置类,从而使该类中的Bean可以被Spring IoC容器管理和使用。

在配置类中,我们可以使用另外两个注解@Bean和@Scope来定义Bean,其中@Bean注解用于定义Bean对象,而@Scope注解用来指定Bean对象的作用域。

总的来说,@Configuration注解能够将一个类定义为Spring Boot应用程序中的配置类,从而使该类中的Bean对象能够被Spring IoC容器进行自动管理和装配。这让应用开发者能够更加专注于应用逻辑的实现,而不必花费精力在繁琐的配置上。 所以@SpringBootConfiguration注解本质上就是一个@Configuration注解,用来标注某个类为 JavaConfig 配置类,有了这个注解就可以在 SpringBoot 启动类中使用@Bean标签配置类了。

@ComponentScan 注解

@ComponentScan 是 Spring Framework 中的一个注解,它用于指定 Spring 容器需要扫描和管理的组件。组件是 Spring 中的一个抽象概念,它包括了 Spring Bean、Controller、Service、Repository 等等。通过 @ComponentScan 注解,可以让 Spring 容器自动扫描和管理这些组件,从而简化应用程序的配置和管理。 @ComponentScan 注解有多个参数,可以用于指定要扫描的组件的位置、排除不需要扫描的组件、指定要排除扫描的组件等等。

默认情况下,Spring Boot会自动扫描主应用程序下的所有组件(@Configuration, @Controller, @Service, @Repository等),但是如果你将组件放在其他包下,那么就需要显式地配置扫描目录。

@EnableAutoConfiguration 注解

这是今天的主角中的主角,自动配置实现的核心注解。 点进这个注解可以发现,如下图所示。

我们重点来看 @Import(AutoConfigurationImportSelector.class)这个注解。 @Import 注解是 它用于将一个或多个类导入到 Spring 容器中,以便于在应用程序中使用。通过 @Import 注解,我们可以将一些非 Spring 管理的类实例化并注册到 Spring 容器中,或者将一些 Spring 管理的配置类导入到当前配置类中,以便于在应用程序中进行统一的配置和管理。 @Import是Spring Framework 中的一个注解,用于在配置类中导入其他配置类或者普通的Java类。

说白了在这里@Import注解的作用就是将 AutoConfigurationImportSelector 这个类导入当前类,这个类就是实现自动配置的核心。 我们继续进入到 AutoConfigurationImportSelector 类:

AutoConfigurationImportSelector实现了DeferredImportSelector接口,我们进入DeferredImportSelector接口

最后,我们发现, AutoConfigurationImportSelector 实际上是实现了 ImportSelector 接口,这个接口只有两个方法,其中我们需要重点关注 selectImports() 方法。

ImportSelector 接口是 Spring Framework 中的一个接口,它可以用于在 Spring 容器启动时动态地导入一些类到 Spring 容器中。通过实现 ImportSelector 接口,并重写其中的 selectImports 方法,我们可以自定义逻辑来确定需要导入的类,从而实现更加灵活的配置和管理。

selectImports 方法是 ImportSelector 接口中的一个方法,用于返回需要导入的类的全限定类名数组。在 Spring 容器启动时,Spring 会扫描所有实现了 ImportSelector 接口的类,并调用其中的 selectImports 方法来确定需要导入的类。

我们进入getAutoConfigurationEntry()方法

这里返回AutoConfigurationEntry类,里面传入了 configurations和exclusions两个参数, configurations参数通过getCandidateConfigurations() 方法得到,我们进入getCandidateConfigurations()方法。

Assert.notEmpty这是一个断言,configurations不能为空 ,如果为空了,给你一段提示:没有自动配置的类找到,在 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports找到,我们将这端配置简称为 .imports 文件,意思就是说,我要去找自动配置类 去 .imports中找,但是我并没有找到,我们需要关注这个配置文件在什么地方,这里先回到pom.xml文件中

进去核心起步依赖,这里面引入了一个:spring-boot-autoconfigure,autoconfigure顾名思义就是自动配置的意思。

接下来我们去找到autoconfigure

在这里我们找到了 AutoConfiguration.imports配置文件

点进去,这个配置文件其实就是配置了一堆类的全类名,这些类都是自动配置类,接下来我们去看看之前演示的DispatcherServlet相关的自动配置类 Ctrl+F:搜索一下

进入:DispatcherServletAutoConfiguration类 , Ctrl+Shift+N全局搜索进入这个类

@AutoConfiguration(after = {ServletWebServerFactoryAutoConfiguration.class})顾名思义,自动配置的意思

@AutoConfiguration点进去,你会发现它也是一个组合注解,组合了一个@Configuration()

说白了DispatcherServletAutoConfiguration这个类是一个配置类

这个类用了@AutoConfiguration注解,更加见名之意它是一个配置类

我们再看@ConditionalOnClass这个注解,是不是很熟悉,前面讲到过:它在这里的意思是,如果你环境里面有DispatcherServlet,那自动配置类就会生效自动注入一个DispatcherServlet的bean对象,如果环境里没有DispatcherServlet,那就不生效,不注入了。

接下来继续往下看

这里内部有一个DispatcherServletConfiguration类,也配置@Configuration注解,里面写一个方法,方法最终返回的就是dispatcherServlet,方法上面有@Bean注解,最终我们可以看到,它注入DispatcherServlet的代码在这里,其实你会发现这里的代码和我们之前写的代码并没有很大的区别,都是写一个方法,让后在方法上面声明一个@Bean注解。

这里最核心的是,它把这个类DispatcherServletAutoConfiguration写到指定的配置文件里面了,那么SpringBoot就可以自动的去读取这个全类名,把这个配置的类的对象注入到Ioc容器中,由于这个配置类的内部还有配置类DispatcherServletConfiguration,内部的配置类里面还有一些方法,这些方法声明了@Bean注解,所以SpringBoot它会继续解析,直到把这些@Bean注解的方法都解析到,执行这些方法,然后把返回值注入到IOC容器里。

因此我们自动配置的核心在哪?核心核心,在这个.imports配置文件中,那么源码我们就到这。

小总结

在SpringBoot2.7版本以前,它自动配置使用的配置文件是 spring.factories,它会从 spring.factories配置文件中读取配置类的全类名,那么在SpringBoot2.7以后到3.0以前,它同时兼容了.imports配置文件以及spring.factories配置文件,在3.0以后只支持.imports配置文件,这个大家要清楚。

通过源码分析,我们知道了,SpringBoot自动配置无非就是提供一个自动配置类,把这个类名写到指定的配置文件中就可以了。

说一说SpringBoot自动配置原理?

希望可以帮到大家,喜欢的给冯宝宝点个关注把,蟹蟹支持!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/315663.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

解释程序基本原理

解释程序基本原理 1、解释程序的基本结构2、高级语言编译与解释方式的比较 语言处理程序是一类系统软件的总称&#xff0c;其主要作用是将高级语言或汇编语言编写的程序翻译成某种机器语言程序&#xff0c;使程序可在计算机上运行。语言处理程序主要分为汇编程序、编译程序和解…

匠心科技BLDC开发板原理图讲解

匠心科技BLDC开发板资料 链接&#xff1a;https://pan.baidu.com/s/1s5YjzRSDLKQvl86lBVAqKA?pwda6cx 提取码&#xff1a;a6cx 解压密码&#xff1a;JXKJ_RALDNWB站视频讲解&#xff08;&#xff09; 链接: 匠心科技直流无刷电机开发板原理图讲解 BLDC的开发板主要分为四个模…

Docker登录MySQL,密码正确却提示密码错误

当我输入了正确的MySQL密码的时候确提示我密码错误&#xff1a; ERROR 1045 (28000): Access denied for user rootlocalhost (using password: YES) docker run --name mysql_master \ -e MYSQL_ROOT_PASSWORD123123 \ -v /root/mysql_master/data:/var/lib/mysql \ -v /root…

Vulnhub-GoldenEye

一、信息收集 nmap探测&#xff1a;nmap -p 1-65535 -T4 -A -v 192.168.1.9 PORT STATE SERVICE VERSION 25/tcp open smtp Postfix smtpd |_smtp-commands: ubuntu, PIPELINING, SIZE 10240000, VRFY, ETRN, STARTTLS, ENHANCEDSTATUSCODES, 8BITMIME, DSN |_…

【Git】本地仓库文件的创建、修改和删除

目录 一、基本信息设置 1、设置用户名2、设置用户名邮箱 二、Git仓库操作介绍 1、创建一个新的文件夹2、在文件内初始化git仓库&#xff08;创建git仓库&#xff09;3、向仓库中添加文件 1.创建一个文件2.将文件添加到暂存区3.将暂存区添加到仓库 4、修改仓库文件 1.修改文件2.…

imgaug库指南(20):从入门到精通的【图像增强】之旅

引言 在深度学习和计算机视觉的世界里&#xff0c;数据是模型训练的基石&#xff0c;其质量与数量直接影响着模型的性能。然而&#xff0c;获取大量高质量的标注数据往往需要耗费大量的时间和资源。正因如此&#xff0c;数据增强技术应运而生&#xff0c;成为了解决这一问题的…

紫光展锐T770安卓核心板_展锐T770 5G核心板规格参数

紫光展锐T770安卓核心板是一款高性能的5G安卓智能模块&#xff0c;拥有先进的6nm制程工艺和强大的性能。板载8GB Ram 256GBROM的内存单元&#xff0c;支持4K H.265/ H.264视频编解码&#xff0c;搭载Android 13以上操作系统&#xff0c;功能丰富。除了支持5G NSA和SA双模式向下…

大数据赋能电竞出海企业发展

近几年电竞行业发展迅速&#xff0c;我国单2022年新增近4万家电竞相关企业&#xff0c;竞争十分激烈。中国电竞市场规模在全球占比19%左右&#xff0c;海外有巨大的增量市场&#xff0c;特别是东南亚、中南亚和拉丁美洲是电竞市场增长最快的地区&#xff0c;在2020至2025年期间…

Hive基础知识(十二):Hive的基本查询

1. 全表和特定列查询 0&#xff09;数据准备 原始数据 dept: 10 ACCOUNTING 1700 20 RESEARCH 1800 30 SALES 1900 40 OPERATIONS 1700 emp&#xff1a; 7369 SMITH CLERK 7902 1980-12-17 800.00 20 7499 ALLEN SALESMAN 7698 1981-2-20 1600.00 300.00 30 7521 WARD SALESM…

【如何使用iPad通过Code App+cpolar实现公网地址远程访问vscode】

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” 文章目录 1. 在iPad下载Code APP2.安装cpolar内网穿透2.1 cpolar 安装2.2 创建TCP隧道 3. iPad远程vscode4. …

Pytorch的默认初始化分布 nn.Embedding.weight初始化分布

一、nn.Embedding.weight初始化分布 nn.Embedding.weight随机初始化方式是标准正态分布 &#xff0c;即均值$\mu0$&#xff0c;方差$\sigma1$的正态分布。 论据1——查看源代码 ## class Embedding具体实现&#xff08;在此只展示部分代码&#xff09; import torch from t…

如何在 SwiftUI 中实现音频图表

文章目录 前言DataPoint 结构体BarChartView 结构体ContentView 结构体实现协议实现线图总结 前言 在可访问性方面&#xff0c;图表是复杂的事物之一。iOS 15 引入了一项名为“音频图表”的新功能。 下面我们将学习如何通过使用 accessibilityChartDescriptor 视图修饰符为任…

数据结构与算法教程,数据结构C语言版教程!(第三部分、栈(Stack)和队列(Queue)详解)五

第三部分、栈(Stack)和队列(Queue)详解 栈和队列&#xff0c;严格意义上来说&#xff0c;也属于线性表&#xff0c;因为它们也都用于存储逻辑关系为 "一对一" 的数据&#xff0c;但由于它们比较特殊&#xff0c;因此将其单独作为一章&#xff0c;做重点讲解。 使用栈…

Histone H3K4me2 Antibody, SNAP-Certified™ for CUTRUN

EpiCypher是一家为表观遗传学和染色质生物学研究提供高质量试剂和工具的专业制造商。EpiCypher推出的CUT&RUN级别的Histone H3K4me2 Antibody符合EpiCypher的批次特异性SNAP-CertifiedTM标准&#xff0c;在CUT&RUN中具有特异性和高效的靶点富集。通过SNAP-CUTANA™K-Me…

智能分析网关V4基于AI视频智能分析技术的周界安全防范方案

一、背景分析 随着科技的不断进步&#xff0c;AI视频智能检测技术已经成为周界安全防范的一种重要手段。A智能分析网关V4基于深度学习和计算机视觉技术&#xff0c;可以通过多种AI周界防范算法&#xff0c;实时、精准地监测人员入侵行为&#xff0c;及时发现异常情况并发出警报…

LeetCode - 1371 每个元音包含偶数次的最长子字符串(Java JS Python C)

题目来源 1371. 每个元音包含偶数次的最长子字符串 - 力扣&#xff08;LeetCode&#xff09; 题目描述 给你一个字符串 s &#xff0c;请你返回满足以下条件的最长子字符串的长度&#xff1a;每个元音字母&#xff0c;即 a&#xff0c;e&#xff0c;i&#xff0c;o&#xff0…

DrGraph原理示教 - OpenCV 4 功能 - 边界填充

今天简单来看一下OpenCV中的边界填充 param src Source image. param dst Destination image of the same type as src and the size Size(src.colsleftright, src.rowstopbottom) . param top the top pixels param bottom the bottom pixels param left the left pixels par…

Redis-浅谈redis.conf配置文件

Redis.conf Redis.conf是Redis的配置文件&#xff0c;它包含了一系列用于配置Redis服务器行为和功能的选项。 以下是Redis.conf中常见的一些选项配置&#xff1a; bind: 指定Redis服务器监听的IP地址&#xff0c;默认为127.0.0.1&#xff0c;表示只能本地访问&#xff0c;可以…

少儿编程 2023年12月电子学会图形化编程等级考试Scratch二级真题解析(判断题)

2023年12月scratch编程等级考试二级真题 判断题(共10题,每题2分,共20分) 26、声音Medieval1的长度是9.68秒,运行下列程序1或程序2都能实现,播放声音2秒后,声音停止角色移动100步 答案:对 考点分析:考查积木综合使用,重点考查声音积木的使用 程序1中用的是等待播完…

暴打小苹果

欢迎来到程序小院 暴打小苹果 玩法&#xff1a;鼠标左键点击任意区域可发招暴打&#xff0c;在苹果到达圆圈时点击更容易击中&#xff0c; 30秒挑战暴打小苹果&#xff0c;打中一次20分&#xff0c;快去暴打小苹果吧^^。开始游戏https://www.ormcc.com/play/gameStart/247 htm…