SpringBoot(4)——SpringBoot自动配置原理

系列文章

1、SpringBoot(1)------创建SpringBoot项目的方式_基于注解方式开发aspectj springboot下载-CSDN博客

2、SpringBoot(2)------SpringBoot入门:微服务-CSDN博客

3、SpringBoot(3)------SpringBoot入门程序及解析-CSDN博客

目录

一、springboot自动配置

1、概述

起步依赖

自动配置

springboot中的SPI机制

2、自动装配是什么及作用

3、Spring自动装配的原理

3.1启动类上的注解

[3.2 @SpringBootConfiguration](#3.2 @SpringBootConfiguration)

[3.3 @EnableAutoConfiguration](#3.3 @EnableAutoConfiguration)


一、springboot自动配置

1、概述

自动配置的功能是其简化运用的关键技术,思想就是约定大于配置,意思就是一个工程约定必须要有事务功能,要有aop功能,要有mvc功能等,所以springboot在创建工程的时候自动把这些功能所需的类实例化并加入到spring容器了,这个就是约定大于配置,约定了必须要有这些功能。

springboot的出现就是为了简化Spring框架的开发,快速构建java web项目。

springboot的两个核心特性就是起步依赖自动配置

起步依赖原理:maven的依赖传递

自动配置原理:条件注入、SPI机制

起步依赖

假如我们没有使用SpringBoot,用的是Spring框架进行web程序的开发,此时我们就需要引入web程序开发所需要的一些依赖。

spring-webmvc依赖:这是Spring框架进行web程序开发所需要的依赖

servlet-api依赖:Servlet基础依赖

jackson-databind依赖:JSON处理工具包

如果要使用AOP,还需要引入aop依赖、aspect依赖

项目中所引入的这些依赖,还需要保证版本匹配,否则就可能会出现版本冲突问题。

如果我们使用了SpringBoot,就不需要像上面这么繁琐的引入依赖了。我们只需要引入一个依赖就可以了,那就是web开发的起步依赖:spring-boot-starter-web。

原因:Maven的依赖传递

自动配置
springboot中的SPI机制

服务发现机制( Service Provider Interface)。它通过在ClassPath路径下的META-INF/services文件夹查找文件,自动加载文件里所定义的类。

(注意:从 SpringBoot 2.7 起自动配置不推荐使用 /META-INF/spring.factories 文件,而是在/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports)文件,这个文件列出了与自动配置相关的接口及其实现类,Spring Boot 启动时会加载这些配置。

这一机制为很多框架扩展提供了可能,比如在Dubbo、JDBC中都使用到了SPI。

SPI可以很灵活的让接口和实现分离,让api提供者只提供接口,第三方来实现,然后可以使用配置文件的方式来实现替换或者扩展,在框架中比较常见,提高框架的可扩展性。

在这我们先介绍两个方法,帮助我们更好的了解自动装配loadFactoryNames()和loadFactories()

  • loadFactoryNames方法获取实现了接口的所有类的名称
java 复制代码
@Test
public void test() {
List<String> strings = SpringFactoriesLoader
.loadFactoryNames(Log.class, ClassUtils.getDefaultClassLoader());

for (String string : strings) { System.out.println(string); 
 }
}
  • loadFactories方法获取实现了接口的所有类的实例
java 复制代码
@Test
public void test1() {
List<String> strings = SpringFactoriesLoader
.loadFactories(Log.class, ClassUtils.getDefaultClassLoader());

for (String string : strings) { System.out.println(string); 
 }
}

springboot中的SPI其实就是加载整个工程里面的spring.factories文件,然后把文件里面的内容建立一个key和value的映射关系,只是这个映射关系是一个类型和list的映射关系。

2、自动装配是什么及作用

springboot的自动装配实际上就是为了从spring.factories文件中获取到对应的需要进行自动装配

的类,并生成相应的Bean对象,然后将它们交给spring容器来帮我们进行管理。

3、Spring自动装配的原理

3.1启动类上的注解

@SpringBootApplication

这个注解是springboot启动类上的一个注解,是一个组合注解,也就是由其他注解组合起来,它的主要作用就是标记说明这个类是springboot的主配置类,springboot应该运行这个类里面的main()方法来启动程序。

我们进入这个注解

其中前四个为元注解

后面蓝框里的三个为这个注解的主要子注解

  • @SpringBootConfiguration
  • @EnableAutoConfiguration
  • @ComponentScan

我们一个一个看

3.2 @SpringBootConfiguration

进入这个注解

这个注解的核心注解为**@Configuration**,进入@Configuration,我们发现这个注解之中包含了一个@Component注解

也就是说这个注解标注在哪个类上,就表示当前这个类是一个配置类,而配置类也是spring容器中的组件,从而使该类中的Bean对象能够被Spring IoC容器进行自动管理和装配。

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

所以@SpringBootConfiguration 注解本质上就是一个@Configuration注解。

3.3@EnableAutoConfiguration

这是实现自动配置的主要注解。我们点击进入这个注解

>@AutoConfigurationPackage

这个注解的作用:将主配置类(@SpringBootApplication标注的类)所在包以及子包里面

的所有组件扫描并加载到spring的容器中,这也就是为什么我们在利用springboot进行开发的时候,无论是Controller还是Service的路径都是与主配置类同级或者次级的原因

>@Import(AutoConfigurationImportSelector.class)

@Import 注解是 它用于将一个或多个类导入到 Spring 容器中,以便于在应用程序中使用。

在这里@Import注解的作用就是将++AutoConfigurationImportSelector++ 这个类导入当前类,这个类就是实现自动配置的核心。

我们继续进入到 AutoConfigurationImportSelector类:

进入DeferredImportSelector:

进入ImportSelector:

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

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

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

在 selectImports 方法中,我们可以自定义逻辑来确定需要导入的类,例如根据某些条件来动态地确定需要导入的类。

继续跟进

**其中:**getAutoConfigurationEntry 方法可以用于获取自动配置类的元数据,以便于分析和调试自动配置机制。

继续进入到 getAutoConfigurationEntry() 方法:

返回值是一个 AutoConfigurationEntry 对象

returnnewAutoConfigurationEntry(configurations, exclusions);

configurations 就是我们需要的自动配置类的元数据

进入到configurations 的获取方法:

它只调用了 SpringFactoriesLoader 的静态方法loadFactoryNames(),还有就是一个断言。

眼熟了吗?这个就是spi的底层原理方法

SpringFactoriesLoader

SpringFactoriesLoader 是 Spring 框架中的一个工具类,用于加载 META-INF/spring.factories 文件中定义的类。它通过loadFactoryNames()方法加载这些自动配置类,从而实现自动配置机制。

继续进入**loadFactoryNames()**方法:

loadFactoryNames()方法里面又调用了一个loadSpringFactories()方法

关键就在这个loadSpringFactories()方法里面,在这个方法里,它会查找所有在META-INF路径下的spring.factories文件

在META-INF/spring.factories这个文件里面的数据是以键=值的方式存储,然后解析这些文

件,找出以EnableAutoConfiguration为键的所有值,以列表的方式返回

相关推荐
Tiger Z13 分钟前
R 语言科研绘图 --- 密度图-汇总
开发语言·程序人生·r语言·贴图
lllsure39 分钟前
【快速入门】MyBatis
java·后端·mybatis
叶雅茗42 分钟前
PHP语言的区块链扩展性
开发语言·后端·golang
爱学习的学姐1 小时前
【精品源码】Java宠物领养网站+SpringBoot+VUE+前后端分离
java·spring boot·宠物
双叶8362 小时前
(C语言)写一个递归函数DigitSum(n),输入一个非负整数,返回组成它的数字之和(递归函数)
c语言·开发语言·数据结构·算法·游戏
字节源流2 小时前
【SpringMVC】常用注解:@SessionAttributes
java·服务器·前端
Json____2 小时前
SpringBoot 和vue前后端配合开发网页拼图10关游戏源码技术分享
vue.js·spring boot·游戏·html·游戏机·拼图游戏·拼图小游戏
Stark、2 小时前
【MySQL】多表查询(笛卡尔积现象,联合查询、内连接、左外连接、右外连接、子查询)-通过练习快速掌握法
数据库·后端·sql·mysql
贫道绝缘子3 小时前
Leetcode-132.Palindrome Partitioning II [C++][Java]
java·c++·算法·leetcode
朝屯暮蒙vi3 小时前
(七)Spring Boot学习——Redis使用
spring boot·redis·学习