从源码级别了解SpringBoot自动配置原理

    科技2022-07-16  112

    前言

    我们知道SpringBoot帮我们完成了底层大量的配置工作,那么这种自动配置原理究竟是如何实现的呢?

    摸索

    大量截图警告⚠️⚠️⚠️⚠️⚠️⚠️

    1、主配置类

    SpringBoot启动的时候加载主配置类,开启了自动配置功能。

    需要额外注意的就是@EnableAutoConfiguration注解

    2、@EnableAutoConfiguration 作用

    利用EnableAutoConfigurationImportSelector给容器中导入一些组件。点击进入查看:

    在这个类中我们可以查看selectImports()方法的内容:

    List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);

    上述这行代码的作用是获取候选的配置。它在类中的位置如下:

    我们可以继续点getCandidateConfigurations()进去看看

    注意到有一条核心语句:SpringFactoriesLoader.loadFactoryNames(),其作用是:

        扫描所有jar包类路径下  META-INF/spring.factories;    把扫描到的这些文件的内容包装成properties对象;    从properties中获取到EnableAutoConfiguration.class类(类名)对应的值,然后把他们添加在容器中

    总结成一句话:将类路径下的META-INF/spring.factories 里面配置的所有EnableAutoConfiguration的值加入到了容器中;

     

    我们可以通过查看添加的依赖,从而进一步佐证这一点:

    每一个这样的  xxxAutoConfiguration类都是容器中的一个组件,都加入到容器中;用他们来做自动配置;

    实战

    以HttpEncodingAutoConfiguration类(作用:Http编码自动配置)为例解释自动配置原理;

    脑袋瓜上有这5个注解:

     

    1:@Configuration

    表示这是一个配置类,以前编写的配置文件一样,也可以给容器中添加组件

    2:@EnableConfigurationProperties

    启动指定类的ConfigurationProperties功能;

    将配置文件中对应的值和ServerProperties绑定起来;

    后面跟着一个类,表示把这个类,即ServerProperties,加入到ioc容器中

    3:@ConditionalOnWebApplication

    根据不同的条件,如果满足指定的条件,整个配置类里面的配置就会生效;

    源自Spring底层@Conditional注解(可以看Spring注解版);

    判断当前应用是否是web应用,如果是,当前配置类生效

    4:@ConditionalOnClass(CharacterEncodingFilter.class) 

    判断当前项目有没有这个类CharacterEncodingFilter;

    这个类是SpringMVC中进行乱码解决的过滤器;

    5:@ConditionalOnProperty

    用来判断配置文件中是否存在某个配置,即是否存在prefix中的spring.http.encoding.enabled;如果不存在,判断也是成立的

    即使我们配置文件中不配置pring.http.encoding.enabled=true,也是默认生效的;

    根据当前不同的条件判断,决定这个配置类是否生效。

    一旦生效,即以上的这些注解都生效了,一但这个配置类生效;这个配置类就会给容器中添加各种组件;这些组件的属性是从对应的properties类中获取的,这些类里面的每一个属性又是和配置文件绑定的;

     

    那接下来的一步是什么呢?我们来看源码:

     使用了@Bean注解,即给容器中添加一个组件,这个组件的某些值需要从properties中获取。如下的这行代码,即 private final Encoding properties;表示 properties已经和SpringBoot的配置文件映射了

     

    我们再看看如下这个构造器,这是有参构造器,其表示只有一个有参构造器的情况下,参数的值就会从容器中拿。

    至于如何拿呢,这里就又涉及到我们前面讲到的第二个注解,即@EnableConfigurationProperties,用以启动指定类的ConfigurationProperties功能;将配置文件中对应的值和HttpEncodingProperties绑定起来;并把HttpEncodingProperties加入到ioc容器中,从而使得我们想用就能用到

    可以看出,所有在配置文件中能配置的属性都是在xxxxProperties类中封装着;配置文件能配置什么就可以参照某个功能对应的这个属性类

    总结

    精髓总结:

    ​       1)、SpringBoot启动会加载大量的自动配置类;

    ​       2)、因此我们看我们需要的功能有没有SpringBoot默认写好的自动配置类;

    ​       3)、(如果有)我们再来看这个自动配置类中到底配置了哪些组件;(只要我们要用的组件有,我们就不需要再来配置了)

    ​       4)、给容器中自动配置类添加组件的时候,会从properties类中获取某些属性。我们就可以在配置文件中指定这些属性的值;

    我们可以进一步总结,在SpringBoot中有非常多的类似的这样的模式,例如形如xxxxAutoConfigurartion是自动配置类,给容器中添加组件。又如xxxxProperties是用来封装配置文件中相关属性;

    我们还可以查看其他的一些自动配置类,ctrl+N搜索*AutoConfiguration

     

    我们可以看到还有Cache的自动配置,我们可以点进去看看

    点进去我们可以再看看可以配置哪些信息:

     

    至此,我们对自动配置原理大致有所了解,不过这仍是管中窥豹,其底层的实现我们也只是走马观花式看了看,其他的部分我们将在之后的学习中不断深化,同时,我也会对其中某些较为复杂的流程以思维盗图或流程图的形式后续更新至本文中。

    Processed: 0.010, SQL: 8