type
status
date
slug
summary
tags
category
icon
password

SpringBoot自动配置原理

1 核心场景启动器是什么?

首先,我们创建一个 SpringBoot 项目时,我们的 pom.xml 文件会导入一个名为 spring-boot-start 的 jar 包。
即使我们不去特意导入这个包,比如只导入 web 环境,也就是 spring-boot-start-web 包,此时我们点进去这个包就会发现这个包下的 pom.xml 文件依然导入了 spring-boot-start
并且不止 web,只要是包名中存在 start- ,它们都算是一个完整的场景,都会导入 spring-boot-start。也就是说即使我们项目的 pom.xml 文件没有导入 spring-boot-start ,但只要存在任意一个 start ,项目依然可以正常执行。
因此,spring-boot-start 也被称之为核心场景启动器

2 关于自动配置类

spring-boot-start 这个包下的 pom.xml 文件导入了以下包:
其中有一个 spring-boot-autoconfigure 包,这个包有一个文件名为 org.springframework.boot.autoconfigure.AutoConfiguration.imports,其中以文字的形式列出了150多个自动配置类的全类名。
notion image
同时它自身的包下存在SpringBoot整合过的所有 xxxAutoConfiguration 类,但是这些配置类并不在项目主程序的包下,而是在 Maven 的外部库里。
notion image

3 @SpringBootApplication 是怎么实现自动导入自动配置类的?

众所周知,@SpringBootApplication 注解由三个注解组成:
  • @SptingBootConfiguration
  • @EnableAutoConfiguration
  • @ComponentScan
SpringBoot 默认只能扫描到主程序所在包下的组件,而 pom.xml 文件导入的包都在外部库里,因此上述所说的 xxxAutoConfiguration 类是扫描不到的,也就不能用。
但是,第二个 @EnableAutoConfiguration 注解点进去会发现另一个注解:
  • @Import(AutoConfigurationImportSelector.class)
这个注解的作用是给容器导入组件,而这个括号中导入的这个类,有一个神奇的方法:selectImports(),而这个方法是用于寻找需要导入的 xxxAutoConfiguration,那么从哪里找呢?正是上面提到的 spring-boot-autoconfigure 包下的 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 这个文件,至此彻底闭环。
但是这些自动配置类不一定全都会生效,这就要提到一个注解
  • @ConditionalOnClass(xxx.class)
这个注解的作用是:只有括号内的类存在外部库中( Maven 中有导入),该配置类才会生效(自动配置类中的代码才会执行,而代码则是负责给 IOC 容器中放入组件的),由此才会形成 “ Maven 中导入什么,我们就能用什么,且不全部导入也不会报错” 的这种情况。
总结:
当你的项目主程序 run 起来的时候,@SpringBootApplication 就会的根据你 pom.xml 文件中导入的 SpringBoot 版本,找到该版本对应的的 spring-boot-autoconfigure 包下的 .imports 文件,进而导入所有的自动配置类,而这些自动配置类依靠 @ConditionalOnClass() 注解和 Maven 动态的刷新外部库 jar 包,从而实现自动配置类的动态执行,最后执行代码的自动配置类会用 @Bean 注解给IOC容器中注入一个或多个组件。
*简直天才般的设计!!

4 application.yml 文件是怎么修改web端口的?

每个自动配置类基本上都存在这个注解:
  • @EnableConfigurationProperties(xxxProperties.class)
这个注解有两个作用:
  1. 把配置文件中指定前缀的属性值封装到 xxxProperties 类(对象/组件)中
  1. 把这个 xxxProperties 类放入IOC容器中。
xxxProperties 这个类中存在这个注解:
  • @ConfigurationProperties(),如:@ConfigurationProperties(prefix = "spring.data.redis")
比如修改端口:
其所用就是指定前缀,将配置文件的 key 和类中的属性值一一对应,最后封装为一个对象放入 IOC 容器中。
因此只需要修改配置文件的值,核心组件的底层参数都能修改。

5 SpringBoot自动装配到底有什么用?

败犬女主也太多了!SpringBoot自动装配到底有什么用?
Loading...