SpringBoot自动配置原理

本文以SpringBoot2.4.4作为案例,不同版本可能有些细小差距

简述

正常来说,我们一般进行spring的配置修改的时候,在application.properties中都是通过idea提示或者从网上搜索相应参数了解到的哪些参数可以进行配置,可以配置成什么样。

IDEA自带提示信息页面:
image.png

但是这些东西其实他是有依据的,我们的依据来源一般来源于:

  • 官方文档
  • 通过配置类(文章完就知道了)


官方文档方式:
如何寻找:

先进入官方网站 https://spring.io/
image.png
选择project->springboot->新页面中的learn
image.pngimage.png
找到所需版本,点击Reference Doc.
image.png
选择Application Properties
image.png
进入的页面就展示着我们所有可以配置的内容
在这里插入图片描述

SpringBoot自动配置原理

启动类

当我们SpringBoot进行启动的时候是从主方法进行启动的。主要加载了SpringBoot主配置类,开启自动配置功能。是使用@SpringBootApplication注解实现的
启动类

@SpringBootApplication注解

@SpringBootApplication它里面最重要的功能是一个@EnableAutoConfiguration的配置注解
image.png

@EnableAutoConfiguration注解

然而@EnableAutoConfiguration的核心功能是通过@Import(AutoConfigurationImportSelector.class)实现的。

@Import注解的作用就是给容器导入一个组件,是Spring的底层注解。

image.png
@EnableAutoConfiguration的作用是:

  • 利用AutoConfigurationImportSelector给容器中导入一些组件

但是它到底导入了哪些组件呢?我们继续往下看。

AutoConfigurationImportSelector类

AutoConfigurationImportSelector这个类中,有一个叫做**selectImports()**的方法。
image.png
看这个方法,它首先在96-98行进行判断是否启用自动配置,如果没有启用直接返回一个空的字符串数组。
image.png
如果自动配置被启用的话,会执行一个叫做getAutoConfigurationEntry()的方法,获取应该导入的自动配置。
再通过将该方法返回值对象中的configuration进行转化,转化成字符串数组进行返回(见99-100行)。
以下为getAutoConfigurationEntry()方法的源代码内容:
image.png
该方法中用到了一个叫做getCandidateConfigurations()的方法,它的作用是获取候选配置。
image.png
getCandidateConfigurations()方法的源代码展示如下:
image.png
它实际上是将类路径下的 META-INF/spring.factories 里面配置的所有EnableAutoConfiguration的值加入到了容器中。具体理解继续往下看。

  • 通过getSpringFactoriesLoaderFactoryClass()方法获取SpringFactoriesLoader用来加载配置候选者的类。
  • 通过SpringFactoriesLoader.loadFactoryNames(……)方法获取应考虑的自动配置类名称,然后判断获取到的列表是否为空?为空抛异常:不为空则返回。


进入getSpringFactoriesLoaderFactoryClass()方法中我们可以看到它返回的是一个EnableAutoConfiguration.class,代表工厂的接口或抽象类。
image.png
然后进入到spring.factories文件中,我们可以找到EnableAutoConfiguration的值
image.png
就相当于把EnableAutoConfiguration所有的值所代表的组件加入到了容器中。
其值中每一个格式为 XXXAutoConfiguration类都是容器中的一个组件,都加入到容器中。他们的作用就是用他们来做自动配置。


我们再进入loadFactoryNames()方法中去。
image.png
此方法的作用是扫描jar包类路径下META-INF/spring.factories这个文件。

使用给定的类加载器从“META-INF / spring.factories”加载给定类型的工厂实现的标准类名。
从Spring Framework 5.3开始,如果多次发现给定工厂类型的特定实现类名称,则将忽略重复项。


进入到loadSpringFactories()方法中
image.png
它首先获取到所有的META-INF/spring.factories文件的url,记做urls。然后通过对urls进行遍历,将每一个url对应的文件包装成properties对象,然后将其中的配置添加到result中,最终以类加载器作为key,result作为value,保存到一个叫做cache的map中,并进行返回。
image.png
也就是说,SpringBoot在启动的时候从类路径下的META-INF/spring.factories中获取EnableAutoConfiguration对应的值,将这些值作为自动配置类导入到容器中,自动配置类就生效了,帮我们进行自动配置工作。
具体值内容如下:
image.png

自动配置内容简单举例

拿其中一个展示,以
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration
为例,我们进到 WebMvcAutoConfiguration 这个类中(代码太长不贴完整源码了,自己去打开源码看吧)
image.png
其实不是没有配置了,只是SpringBoot的自动配置功能帮我们都已经提前配置好默认的了(使用配置类)。
所有的默认配置都在 spring-boot-autoconfigure-2.4.4.jar 的这个位置。
image.png

以HttpEncodingAutoConfiguration为例

以HttpEncodingAutoConfiguration为例解释自动配置原理。

@Configuration(proxyBeanMethods = false) //表示是一个配置类
@EnableConfigurationProperties(ServerProperties.class) //启动指定类的ConfigurationProperties功能
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
@ConditionalOnClass(CharacterEncodingFilter.class)
@ConditionalOnProperty(prefix = "server.servlet.encoding", value = "enabled", matchIfMissing = true)
public class HttpEncodingAutoConfiguration {
    // ...
}
  • @Configuration
    • 表示是一个配置类,类似于以前的配置文件一样,也可以给容器中加入组件
  • @EnableConfigurationProperties
    • 启用configu rationProperties功能
    • 进入到对应的ServerProperties类中
      • @ConfigurationProperties(prefix = “server”, ignoreUnknownFields = true)
        • 从配置文件中获取指定的值和bean属性进行绑定,bean中有什么属性,就可以在配置文件中配置什么值

spring底层有个@Conditional注解,根据不同条件,如果满足指定条件,整个配置类才会生效

  • @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
    • 判断当前是否是Web应用,是的话配置类生效,不是不生效
  • @ConditionalOnClass(CharacterEncodingFilter.class)
    • 判断当前项目有没有括号中的那个类,有的话配置类生效,没有不生效
  • @ConditionalOnProperty(prefix = “server.servlet.encoding”,,value = “enabled”, matchIfMissing = true)
    • 判断配置文件中是否存在以server.servlet.encoding开头并且名称为value的配置项
    • matchIfMissing=true代表如果不存在也默认为true

这是类上面有的就解释了一下,其他的@Conditional系列注解查看官方文档了解。

image.png
但是我们平时不可能一个一个文件去看究竟哪些XXXAutoConfiguration类被加载了,我们可以在application.properties文件中设置 debug=true 开启调试模式,在启动SpringBoot项目的时候,控制台就会打印自动配置报告,告诉我们哪些自动配置类生效了。






















































相关推荐
©️2020 CSDN 皮肤主题: 点我我会动 设计师:白松林 返回首页