【SpringBoot 自动配置】-EnableAutoConfiguration 注解

news2025/2/25 3:41:37

【SpringBoot 自动配置】-EnableAutoConfiguration 注解

续接上回 【Spring Boot 原理分析】- 自动配置 与【SpringBoot 自动配置】- Enable*注解 ,在前面笔者分析了在 SpringBoot 自动装配中的最重要的两个注解类, @Condition@EnableAutoConfiguration

哎~说到这里,那首先我们跟随笔者一起先回忆一下这两个注解的在 SpringBoot 当中充当什么角色呢?

梦回 Condition

✈️ Condition 注解:是在 Spring 4.0 增加的条件判断的一个功能,通过该功能可以实现选择性的创建 Bean

官方解释如下所示:

图1

                                     [SpringBoot 自动配置-图1]

具体的使用方式就是,将该注解作用于我们要注入的 Bean 的 Config 配置类返回 Bean 对象的方法上例如下面的案例

@Configuration
public class UserConfig {
    @Bean
    @Conditional(".....")
    public User user(){
        return new User();
    }
}
                                     [SpringBoot 自动配置-code-1]

@Conditional 注解的内部需要我们的传入具体的实参,通过上面的 [SpringBoot 自动配置-图1] 可以看到,我们的 @Conditional 注解中解释的参数是一个 Condition 的 Class 类型的数组,所以我们的如果说,要让我们的对象是通过条件触发注入到容器当中的,那么我们必须自己定义一个 Condition 的实现类,并将该定义的实现类通过参数的形式添加到 @Conditional 的注解上。

// 自定义注解实现类
public class ClassCondtion implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        boolean result=false;
        //条件不满足
         **** ** 
        //条件满足 
        result=true;
        return result;
    }
}
                                     [SpringBoot 自动配置-code-2]

我们通过对于实现类返回值得控制 ( true[加载] / false[不加载] ) 便可以实现在 SpringBoot 容器创建的时候更加条件决定是否加载该对象到容器当中。

🛸 当然对于 @Conditional 注解在此基础上,官方延伸出了一些功能性更强的注解,比如:

@ConditionalOnClass :判断是否存在这个类文件,如果有这个文件就相当于满足条件,然后可以注入到容器当中

@ConditionalOnBean: bean存在的时候注入,不存在的时候不注入

@ConditionalOnProperty: 主要可用于通过和 SpringBoot 当中 application 配置文件来使用

所以 Condition 注解就一句话总结就是,该注解作用在对象的配置类的对象方法上,通过条件触发创建 Bean

糟糕的梦魇 @EnableAutoConfiguration

紧接上篇的余尾,大致回忆一下 @EnableAutoConfiguration 注解的作用,看该注解的名字就知道该注解的作用就是启动自动配置。

上回主要说的就是关于 @Import 注解的详细使用,以及对 ImportSelector 接口的分析,那么这两个为什么会这么重要呢?

🛫 我们继续从 SpringBoot 的启动类上的 SpringBootApplication 注解说起,搬好小板凳!!!!!起飞

image-20230221194625207

                                     [SpringBoot 自动配置-图2]

image-20230221194655982

                                     [SpringBoot 自动配置-图3]

image-20230221194720158

                                     [SpringBoot 自动配置-图4]

image-20230221194823600

                                     [SpringBoot 自动配置-图5]

image-20230221194906945

                                     [SpringBoot 自动配置-图6]

image-20230221195023692

                                     [SpringBoot 自动配置-图7]

============================================================================================================================

🪂 这几幅图的连环炮,大家都还和我一样,都挺的住吧。。。如果没挺住,哎~~先别骂,笔者我第一次,不,第 N 次看的时候其实和你们一样,准备放弃自己的职业生涯,到我们公司楼下去应聘保安的。

🚠 好从现在下面的分割线开始,大家先学会一点,就是忘记,没错先忘记之前看的并用你聪明的小脑袋瓜理解的所以的点,就像太极拳一样,当你全部忘记的时候,就是你学会的时候。跟着笔者一步一步来,我们从后向前看。。。

===========================================================================================================================

最后一张图,也就是 [SpringBoot 自动配置-图7] 我们看到一个 ImportSelector 字面意思就是导入选择器,那么这个选择器怎么使用呢?

既然是接口,那必须要相应的实现了,所以首先必须有其具体的实现类,继续向上看 [SpringBoot 自动配置-图6] 中的 DeferredImportSelector 接口基础了 ImportSelector , 再继续 [SpringBoot 自动配置-图5] 可以看到 AutoConfigurationImportSelector 实现了 DeferredImportSelector 接口,所以也就是说 AutoConfigurationImportSelector 其实就是 ImportSelector 的实现类。

接着继续看 [SpringBoot 自动配置-图4]@Import 注解中将 ImportSelector 接口的实现类 AutoConfigurationImportSelector 的类对象加载其中。

还记得我们前面提到过的 @Import 注解的四种用法吗?

  1. 导入 Bean

  2. 导入配置类

  3. 导入 ImportSelector 实现类,一般用于加载配置文件的类

  4. 导入 ImproBeanDefintionRegistrar 实现类

而这里 SpringBoot 官网的启动类的自动加载就是使用的第三种,通过导入 ImportSelector 的实现类 AutoConfigurationImportSelector 来实现指定类的加载的。

🚀 所以大家懂的了吧,原来啊,是这样的 @EnableAutoConfiguration 注解是一个复合注解,主要由 @Import 注解加实现类 AutoConfigurationImportSelector 控制,来完成对 Bean 的初始化注入啊。

自动加载的心脏 - AutoConfigurationImportSelector

image-20230221201012868

                                     [SpringBoot 自动配置-图8]

可以看到的是 ImportSelector 接口中的 selectImports 方法返回的是一个字符串类型的数组,注释中指明到返回的是指定的类的全限定名。

所以我们返回到 AutoConfigurationImportSelector 来看看他是具体怎么实现 selectImports 方法的呢?

image-20230221201858469

                                     [SpringBoot 自动配置-图9]

通过 [SpringBoot 自动配置-图9] 可以看到在 selectImports 的方法中调用了该类中的 getAutoConfigurationEntry 方法获取了自动加载的条目,然后转化成 Stirng 类型的数组并返回。

image-20230221202216178

                                     [SpringBoot 自动配置-图10]

通过 [SpringBoot 自动配置-图10] 可以看到 getAutoConfigurationEntry 方法中在调用 getCandidateConfigurations 方法获取了所有需要加载的配置集合。

protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
    List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
    Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.");
    return configurations;
}
                                     [SpringBoot 自动配置-code-3]

image-20230221202705672

                                     [SpringBoot 自动配置-图11]

通过 [SpringBoot 自动配置-图11] 可以看到返回的是自动需要装配的类的全限定名,并且断言是否找到 META-INF/spring.factories 文件。

🎷 哎~~ 说到这里,那么这里 spring.factories 文件到底是什么呢?为什么通过该文件,就可以找到需要加载类的全限定名,提取作为字符串集合返回呢?

我们接着看。。。。。。

随便找一个自动加载的依赖我进行查看,其目录的结构以及目录下的 spring.favtories 文件

image-20230221203326680

                                     [SpringBoot 自动配置-图12]

image-20230221203446067

                                     [SpringBoot 自动配置-图13]

可以看到 spring-boot-autoconfig 包下的 spring.favtories 文件中有大量的自动加载的类路径资源

看到这里,聪明的你是不是以及明白了呢,其实这些就是 SpringBoot 通过 @import 能实现自动加载的原因了,原来是 SpringBoot 的启动类上有一个子注解叫做 @import 而该注解呢,通过对 ImportSelect 接口的实现类AutoConfigurationImportSelector 类下的 selectImports 方法,该方法通过其他方法的调用实现对 spring.favtories 配置文件中的指定类路径获取从而实现了自动注入。

其实看到这里大家有没有想到一点呢?

就单单一个 spring-boot-autoconfig 的包下就有这么多的配置,那么对于其他的包导入后是不是也都是 spring.favtories 文件下的全部导入呢?

其实并不是这样啦,如果将 spring.favtories 配置文下所有的类路径都导入,那样就会让我们的 SpringBoot 变得很看起来 “繁重” ,不知大家还记得之前提到过的 @ImportSelector 注解的衍生注解吗?比如 @ConditionalOnClass @ConditionalOnBean @ConditionalOnProperty 而其实在我们导入的 jar 包中都是有 @ImportSelector 注解的衍生注解去约束的,从而保证导入到容器中的对象都是高可用的。

看到这里,相比大家其实对 SpringBoot 的自己装载都有了一个清晰的认识啦,关于如何自定义一个类似于第三方提供的依赖的那种自动更具配置文件进行自动导入,我们下一篇再解释咯。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

从0到1搭建大数据平台之监控

大家好&#xff0c;我是脚丫先生 (o^^o) 大数据平台设计中&#xff0c;监控系统尤为重要。 它时刻关乎大数据开发人员的幸福感。 试想如果半夜三更&#xff0c;被电话吵醒解决集群故障问题&#xff0c;那是多么的痛苦&#xff01;&#xff01;&#xff01; 但是不加班是不可…

shiro总结

0x00 前言 此篇作为shiro总结篇&#xff0c;用于查漏补缺。 利用工具推荐&#xff1a;https://github.com/j1anFen/shiro_attack 0x01 反序列化 1.shiro 124 shiro 124&#xff0c;因为AES加密秘钥硬编码导致反序列化漏洞&#xff0c;124修复 Java 代码审计——shiro 1.2…

React 虚拟DOM的前世今生

引文 通过本文你将了解到 什么是虚拟DOM&#xff1f;虚拟DOM有什么优势&#xff1f;React的虚拟Dom是如何实现的&#xff1f;React是如何将虚拟Dom转变为真实Dom&#xff1f; 一、前言 要了解虚拟DOM&#xff0c;我们先明确一下DOM的概念。 根据MDN的说法&#xff1a; 文档…

Win10关闭自动更新

Win10关闭自动更新第一步&#xff1a;修改电脑系统时间第二步&#xff0c;设置自动更新时间第三步&#xff1a;再次修改系统时间为正确时间因为国内使用的操作系统&#xff0c;很多‍是非正版的系统&#xff0c;如果更新了系统&#xff0c;很容易造成电脑蓝屏&#xff0c;系统运…

90%的合同麻烦都源于签约“漏洞”,君子签电子签章闭坑指南来了!

业务签约中&#xff0c;有哪些合同麻烦呢&#xff1f;文字套路、印章造假、假冒代签、乱签漏签、信息泄露…事实上&#xff0c;这些签约“漏洞”都是源于签约风险排查不到位&#xff0c;管控不力而导致的&#xff0c;以至于后期履约中纠纷也不断。 君子签针对业务签约中的各类…

小黑子的python入门到入土:第二章

python零基础入门到入土2.0python系列第二章1. 三目运算符2. 运算符优先级3. if 语句3.1 简单的if语句3.2 if-else 语句3.3 if-elif-else 语句3.4 if 语句注意点4. pass 关键字5. 猜拳游戏案例6. while 循环语句7. while 练习8. range9. for...in 循环的使用10. break 和contin…

小林coding

一、图解网络 问大家&#xff0c;为什么要有TCP/Ip网络模型&#xff1f; 对于同一台设备上的进程通信&#xff0c;有很多种方式&#xff0c;比如有管道、消息队列、共享内存、信号等方式&#xff0c;对于不同设备上的进程通信&#xff0c;就需要有网络通信&#xff0c;而设备是…

约束优化:PHR-ALM 增广拉格朗日函数法

文章目录约束优化&#xff1a;PHR-ALM 增广拉格朗日函数法等式约束非凸优化问题的PHR-ALM不等式约束非凸优化问题的PHR-ALM对于一般非凸优化问题的PHR-ALM参考文献约束优化&#xff1a;PHR-ALM 增广拉格朗日函数法 基础预备&#xff1a; 约束优化&#xff1a;约束优化的三种序…

【MyBatis】逆向工程与分页插件

11、MyBatis的逆向工程 11.1、创建逆向工程的步骤 正向工程&#xff1a;先创建Java实体类&#xff0c;由框架负责根据实体类生成数据库表。 Hibernate是支持正向工程的。 逆向工程&#xff1a;先创建数据库表&#xff0c;由框架负责根据数据库表&#xff0c;反向生成如下资源…

公司技术团队为什么选择使用 YApi 作为 Api 管理平台?

在 2021 年 12 月份的时候我就推荐过一款软件程序员软件推荐&#xff1a;Apifox&#xff0c;当时体验了一下里面的功能确实很实用&#xff0c;但是当时公司有一套自己的 API 管理方案&#xff0c;所有 Apifox 暂时就没在内部使用。 直到最近要使用其他的 API 管理方案的时候才…

SAP ERP系统PP模块MRP运行参数说明

SAP/PP模块运行MRP(MD01/MD02)的界面有很多参数&#xff0c;这些参数的设置上线前由PP业务顾问根据实际业务需求定义好的&#xff0c;上线后一般不会轻易去调整&#xff0c;对于一般操作用户&#xff0c;按手册操作就行&#xff0c;不需要深入了解这些参数&#xff0c;但作为负…

收藏这几个开源管理系统做项目,领导看了直呼牛X!

项目SCUI Admin 中后台前端解决方案Vue .NetCore 前后端分离的快速发开框架next-admin 适配移动端、pc的后台模板django-vue-admin-pro 快速开发平台Admin.NET 通用管理平台RuoYi 若依权限管理系统Vue3.2 Element-Plus 后台管理框架Pig RABC权限管理系统zheng 分布式敏捷开发…

Redis的下载与安装

为便于大多数读者学习本套教程&#xff0c;教程中采用 Windows 系统对 Redis 数据库进行讲解。虽然 Redis 官方网站没有提供 Windows 版的安装包&#xff0c;但可以通过 GitHub 来下载 Windows 版 Redis 安装包&#xff0c;下载地址&#xff1a;点击前往。 注意&#xff1a;Win…

企业级解决方案Redis

缓存预热“宕机”服务器启动后迅速宕机1. 请求数量较高2. 主从之间数据吞吐量较大&#xff0c;数据同步操作频度较高解决方案前置准备工作&#xff1a;1. 日常例行统计数据访问记录&#xff0c;统计访问频度较高的热点数据2. 利用LRU数据删除策略&#xff0c;构建数据留存队列例…

全链路压力测试

压力测试的目标&#xff1a; 探索线上系统流量承载极限&#xff0c;保障线上系统具备抗压能力 复制代码 如何做全链路压力测试&#xff1a; 全链路压力测试&#xff1a;整体步骤 容量洪峰 -》 容量评估 -》 问题发现 -》 容量规划 全链路压力测试&#xff1a;细化过程 整体目…

Apache Shiro与Spring Security对比

Apache Shiro VS Spring Security 1.Spring Security 官方文档&#xff1a;https://spring.io/projects/spring-security#overview介绍&#xff1a; Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它提供了一组可以在Spr…

Java 基础(3)—synchornized 关键字简单理解

一、synchronized 修饰同步代码块 用 synchronized 修饰代码段作为同步锁&#xff0c;代码如下&#xff1a; public class LockDemo {public Object object new Object();public void show(){synchronized (object) {System.out.println(">>>>>>hell…

java Spring aop多个增强类作用于同一个方法时,设置优先级

我们先来模拟这种情况 我们先创建一个java项目 然后 引入Spring aop需要的基本依赖 然后 在src下创建一个包 我这里叫 Aop 在Aop包下创建一个类 叫 User 参考代码如下 package Aop;import org.springframework.stereotype.Component;Component public class User {public vo…

Java-形参与返回值

Java学习之道-1 一、形参与返回值 平时在进行代码编写的时候大多都是以变量作为形参或者以某种数据类型比如int、String或者Boolean等等作为返回值&#xff0c;本次主要介绍以下三种作为形参与返回值的情况 1、类名作为形参与返回值 类名&#xff0c;顾名思义是定义的class类&a…

国家级高新区企业主要经济指标(2012-2021年)

数据来源&#xff1a;国家统计局 时间跨度&#xff1a;2012-2021 区域范围&#xff1a;全国&#xff08;及各分类统计指标&#xff09; 指标说明&#xff1a;手工提取最新的中国统计年鉴数据中各个excel指标表&#xff0c;形成各个指标文件的多年度数据&#xff0c;便于多年…