springboot自动配置原理以及spring.factories文件的作用详解

news2025/2/27 22:07:17

一、springboot 自动配置原理

先说说我们自己的应用程序中Bean加入容器的办法:

bean加入容器

我们在应用程序的入口设置了 @SpringBootApplication标签,默认情况下他会扫描所有次级目录。

如果增加了 scanBasePackages属性,就会扫描所有被指定的路径及其次级目录。

那么它在扫描的是什么东西呢?

是这个:@Component

所有被扫描到的 @Component,都会成为一个默认的singleton(单例,即一个容器里只有一个对象实体)加入到容器中。

认识到以上这点,便于我们理解springboot自动配置的机制。

接下来让我们看看在自己的应用程序中实现配置的方法。

如图:

RestTemplateConfig

这里我们设置了一个配置,往容器中加入了一个RestTemplate。

首先说 @Configuration,这个标签继承了 @Component标签,我们可以在标签内容看到:

Configuration

可以看到其中是有 @Component标签的,所以,@Configuration会被 @SpringBootApplication扫描到,进而把它和它下面的 @Bean加入容器,于是我们 RestTemplate的内容就配置完成了,在后续的使用中,我们就可以直接从容器中拿出RestTemplate使用它。

对于在maven中引用的其他外部包加入容器的过程,需要用到spring.factories。

二、spring.factories文件的作用

在springboot运行时,SpringFactoriesLoader 类会去寻找

publicstatic final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";

我们以mybatis-plus为例。

首先我们引入:

maven引包

然后去maven的依赖里看它的自动配置类MybatisPlusAutoConfiguration

MybatisPlusAutoConfiguration

可以看到有上文提到的 @Configuration,还有从application.yml载入自动配置的 @EnableConfigurationProperties({MybatisPlusProperties.class})

这个注解的具体内容请查看我另一篇博文,对其进行了解释:

迅速学会@ConfigurationProperties的使用

也就是说,springboot只要能扫描到MybatisPlusAutoConfiguration类的 @Configuration注解,其中的所有配置就能自动加入到容器中,这一过程由上面提到的SpringFactoriesLoader 起作用,它会去寻找 “META-INF/spring.factories” 文件,我们可以在 mybatis-plus的依赖中找到它:

SpringFactoriesLoader为什么要读取它呢?因为它内部是这样的

factories

spring.factories用键值对的方式记录了所有需要加入容器的类,EnableAutoConfigurationImportSelector的selectImports方法返回的类名,来自spring.factories文件内的配置信息,这些配置信息的key等于EnableAutoConfiguration,因为spring boot应用启动时使用了EnableAutoConfiguration注解,所以EnableAutoConfiguration注解通过import注解将EnableAutoConfigurationImportSelector类实例化,并且将其selectImports方法返回的类名实例化后注册到spring容器。

以上内容是springboot获得这些类的方式,如果你想要实现自己的自动配置,就将你的类通过键值对的方式写在你的spring.factories即可,注意,值是你的自动配置类,键必须是org.springframework.boot.autoconfigure.EnableAutoConfiguration

三、spring.factories 的妙用

现象

在阅读 Spring-Boot 相关源码时,常常见到 spring.factories 文件,里面写了自动配置(AutoConfiguration)相关的类名,因此产生了一个疑问:“明明自动配置的类已经打上了 @Configuration 的注解,为什么还要写 spring.factories 文件?

用过 Spring Boot 的都知道

@ComponentScan 注解的作用是扫描 @SpringBootApplication 所在的 Application 类所在的包(basepackage)下所有的 @component 注解(或拓展了 @component 的注解)标记的 bean,并注册到 spring 容器中。

那么问题来了

在 Spring Boot 项目中,如果你想要被 Spring 容器管理的 bean 不在 Spring Boot 包扫描路径下,怎么办?

解决 Spring Boot 中不能被默认路径扫描的配置类的方式,有 2 种:

(1)在 Spring Boot 主类上使用 @Import 注解

(2)使用 spring.factories 文件

以下是对 使用 spring.factories 文件的简单理解

Spring Boot 的扩展机制之 Spring Factories

Spring Boot 中有一种非常解耦的扩展机制:Spring Factories。这种扩展机制实际上是仿照Java中的SPI扩展机制来实现的。

什么是 SPI 机制?

SPI 的全名为 Service Provider Interface.大多数开发人员可能不熟悉,因为这个是针对厂商或者插件的。在java.util.ServiceLoader的文档里有比较详细的介绍。

java SPI

java SPI 就是提供这样的一个机制:为某个接口寻找服务实现的机制。有点类似IOC的思想,就是将装配的控制权移到程序之外,在模块化设计中这个机制尤其重要。

Spring Boot 中的 SPI 机制

在 Spring 中也有一种类似与 Java SPI 的加载机制。它在 resources/META-INF/spring.factories 文件中配置接口的实现类名称,然后在程序中读取这些配置文件并实例化。

在 Spring 中也有一种类似与 Java SPI 的加载机制。它在 resources/META-INF/spring.factories 文件中配置接口的实现类名称,然后在程序中读取这些配置文件并实例化。

这种自定义的SPI机制是 Spring Boot Starter 实现的基础。

Spring Factories 实现原理是什么?

spring-core 包里定义了 SpringFactoriesLoader 类,这个类实现了检索 META-INF/spring.factories 文件,并获取指定接口的配置的功能。在这个类中定义了两个对外的方法:

实现

上面的两个方法的关键都是从指定的 ClassLoader 中获取 spring.factories 文件,并解析得到类名列表,具体代码如下

SpringFactoriesLoader

从代码中我们可以知道,在这个方法中会遍历整个 spring-boot 项目的 classpath 下 ClassLoader 中所有 jar 包下的 spring.factories文件。也就是说我们可以在自己的 jar 中配置 spring.factories 文件,不会影响到其它地方的配置,也不会被别人的配置覆盖。

Spring Factories 在 Spring Boot 中的应用

在 Spring Boot 的很多包中都能够找到 spring.factories 文件,接下来我们以 spring-boot-autoconfigure 包为例进行介绍

spring-boot-autoconfigure 包

结合前面的内容,可以看出 spring.factories 文件可以将 spring-boot 项目包以外的 bean(即在 pom 文件中添加依赖中的 bean)注册到 spring-boot 项目的 spring 容器。

由于@ComponentScan 注解只能扫描 spring-boot 项目包内的 bean 并注册到 spring 容器中,因此需要 @EnableAutoConfiguration 注解来注册项目包外的bean。

而 spring.factories 文件,则是用来记录项目包外需要注册的bean类名。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

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

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

相关文章

SAP ABAP根据事务码查找增强最直接的方法

下面是为任意事务代码查找用户出口的步骤: 方法一: 第 1 步:使用 事务代码:SE93。输入您要搜索用户出口的 事务代码。 在我们的场景中,我们将使用 CO11N。 第 2 步:点击显示: 第 3 步&#xf…

2023年浙江安全员精选真题题库及答案

百分百题库提供建筑安全员考试试题、安全员证考试真题、安全员证考试题库等,提供在线做题刷题,在线模拟考试,助你考试轻松过关。 268.注册执业人员未执行法律法规和工程质量强制性标准,造成重大安全事故的,(). A.停止执业 B.5年不予注册 C.10年不予注…

29-Golang中的切片

Golang中的切片基本介绍切片在内存中的形式切片使用的三种方式方式一:方式二:方式三:切片使用的区别切片的遍历切片注意事项和细节说明append函数切片的拷贝操作string和slice基本介绍 1.切片是数组的一个引用,因此切片是引用类型…

采用Spring配置文件管理Bean

文章目录采用Spring配置文件管理Bean(一)创建Maven项目(二)添加Spring依赖(三)创建杀龙任务类(四)创建勇敢骑士类(五)采用传统方式让勇敢骑士完成杀龙任务&am…

2.14日报

今日修改token传参异常bug 国际化bug修复:code中的success只有第一次调用识别lang 没继承BaseController 异常处理的三种方式 1|0一. Controller层面上异常处理 ExceptionHandler 说明:针对可能出问题的Controller,新增注解方法ExceptionHandler. Con…

论文投稿指南——中文核心期刊推荐(农学)

【前言】 🚀 想发论文怎么办?手把手教你论文如何投稿!那么,首先要搞懂投稿目标——论文期刊 🎄 在期刊论文的分布中,存在一种普遍现象:即对于某一特定的学科或专业来说,少数期刊所含…

进程调度(4.1)

进程调度 进程调度是操作系统的基本功能,在多道程序系统中,内存中有多个进程,每个进程交替的去使用处理机,而合理的调度是至关重要的。处理机的调度有三种类型,分别是高级调度、中级调度、低级调度,其中低…

dvwa靶场上的 RCE漏洞+暴力破解的简单学习

记录一下自己重新开始学习web安全之路⑦。 操作系统的一些简单基础: windows: 查询IP地址:ipconfig 查看完整的网卡信息:ipconfig/all 列出当前目录下的文件信息:dir 切换目录:cd 读取文件内容&…

PID控制算法进阶

关于PID控制算法基础概念在本文不再重复了,详情可参考:PID控制算法基础介绍 本文主要从PID算法代码实现,代码解析,理论进阶,PID调参等方向进行阐述。 目录位置式PID和增量式PID1.1 位置式PID1.2 增量式PID1.3 位置式和…

Spring3之基于Aspect实现AOP

简介 使用 Aspect 搭配 Spring 可轻松实现 AOP;本章将通过一个完整示例演示如何实现这一功能 实现步骤 修改 beans.xml 配置文件的 schema 部分;可以在 spring-framework-reference.html 文件通过搜索关键字 “/aop” 找到配置 schema,然后…

Linux安装ElasticSearch

下载地址:https://www.elastic.co/cn/downloads/past-releases#elasticsearch 1 版本选择 ElasticSearch 7 及以上版本都是自带的 jdk,假如需要配置指定的 jdk 版本的话,可以在 es 的 bin 目录下找到elasticsearch-env.bat 这个文件&#x…

(学习日记)2023.2.12

写在前面: 由于时间的不足与学习的碎片化,写博客变得有些奢侈。 但是对于记录学习(忘了以后能快速复习)的渴望一天天变得强烈。 既然如此 不如以天为单位,以时间为顺序,仅仅将博客当做一个知识学习的目录&a…

谷粒商城:订单中心概念解析

1、订单中心 电商系统涉及到 3 流,分别时信息流,资金流,物流,而订单系统作为中枢将三者有机的集 合起来。 订单模块是电商系统的枢纽,在订单这个环节上需求获取多个模块的数据和信息,同时对这 些信息进行加…

千峰jquery进阶内容

封装选项卡&#xff1a; HTML部分&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta http-equiv"X-UA-Compatible" content"IEedge" /><meta name"viewport&…

在基于全志D1s的芒果派麻雀上运行国产开源rt-smart系统

想必RT-Thread系统大家不陌生了&#xff0c;RT-Thread Smart&#xff08;简称 rt-smart&#xff09;是基于 RT-Thread 操作系统衍生的新分支&#xff0c;面向带 MMU&#xff0c;中高端应用的芯片&#xff0c;例如 ARM Cortex-A 系列芯片&#xff0c;MIPS 芯片&#xff0c;带 MM…

ELK采集MySQL慢日志实现

文章目录一、ELK采集MySQL慢日志架构二、filebeat三、logstash四、eskibana一、ELK采集MySQL慢日志架构 MySQL 服务器安装 Filebeat 作为 agent 收集 slowLogFilebeat 读取 MySQL 慢日志文件做简单过滤传给 Kafka 集群Logstash 读取 Kafka 集群数据并按字段拆分后转成 JSON 格…

春季开学即将到来!大学生活必备数码清单奉上

马上就要开学了&#xff0c;你的返校装备是否已经准备齐全了呢&#xff1f;对于高校学生来说&#xff0c;很多数码产品都属于必备装备&#xff0c;比如下面这几款产品就受到了大量年轻消费者的喜爱&#xff0c;在它们的帮助下能够让大家的学习时光变得更快乐。1、不入耳黑科技骨…

DM8:DMDSC共享存储集群搭建-配置文件准备

DM8:DMDSC共享存储集群搭建-配置文件准备1 环境介绍2 配置文件2.1 EP73 节点配置文件2.1.1 dmdcr_cfg.ini2.1.2 dmasvrmal.ini2.1.3 dmdcr.ini2.1.4 dminit.ini2.1.5 dmcssm.ini2.1.6 配置文件就绪2.2 EP74 节点配置文件2.2.1 dmdcr.ini1 环境介绍 使用裸设备搭建 2 节点 DMDS…

从零开始的数模(二十六)单因素方差分析

目录 一、概念 1.1相关概念 1.2用途 1.3数据要求&#xff1a;独立性/正态性/方差齐性 1.4步骤 ​编辑1.5专业名词 二、基于python的单因素方差分析 2.2单因素方差分析的作用 一、概念 1.1相关概念 单因素方差分析是一种常用的统计分析方法&#xff0c;它用于比较一个因…

csgo搬砖项目,门槛最低的副业就是它(内附入门知识及选品技巧)

CSGO搬砖如何选择游戏饰品(装备&#xff09;&#xff1f;相信很多朋友一定很关心这个问题&#xff0c;因为如何选品直接关系到该装备是否快速出售&#xff0c;而且也关系到账号整体盈收状况。那么今天阿阳就来好好聊聊如何选择Steam装备以及饰品的各项知识点。 Steam搬砖如何选…