SpringBoot-05-自动配置原理

SpringBoot-05-自动配置原理

本篇解决以下问题

  • 配置文件到底能写什么?怎么写?

    • spring.factories 和 配置文件之间的联系
      • 不卖关子:所有yaml可以配置的东西都在xxxProperties里有
      • xxxProperties.java文件在spring.factories存在
      • 同时每一个xxxProperties.java 对应着一个xxxAutoConfiguration.java
    • 本质:yaml中能配置的属性都是xxxProperties类中所有的属性
  • SpringBoot官方文档中有大量的配置,我们无法全部记住

  • 网站 : https://docs.spring.io/spring-boot/docs/2.2.6.RELEASE/reference/html/using-spring-boot.html

1. 自动配置原理分析

  • HttpEncodingAutoConfiguration(Http编码自动配置)为例解释自动配置原理;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
// 1. Configuration表示这是一个配置类,和以前编写配置文件一样,也可以给容器中添加组件。
@Configuration(proxyBeanMethods = false)
// 2. 启动指定的类ConfigurationProperties功能:
//2.1 进入这个HttpProperties查看,将配置文件中对应的值和HttpProperties绑定起来
//2.2 并把HttpProperties加入到ioc容器中
@EnableConfigurationProperties(HttpProperties.class)
// 3. Spring底层@Conditional注解
// 3.1 根据不同的条件判断,如果满足指定的条件,整个配置类里面的配置就会生效
// 3.2 这里的意思是判断当前的应用是否是web应用,如果是,当前配置类生效
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
//判断当前的项目有没有这个类CharacterEncodingFilter;SpringMVC中进行乱码解决的过滤器;
@ConditionalOnClass(CharacterEncodingFilter.class)
//判断配置文件中是否存在某个配置spring.http.encoding
//如果不存在,判断也是成立的
//即使我们配置文件中不配置pring.http.encoding.enabled=true,也是默认生效的;
@ConditionalOnProperty(prefix = "spring.http.encoding", value = "enabled", matchIfMissing = true)
public class HttpEncodingAutoConfiguration {
// 这里已经和SpringBoot配置文件有映射了
private final HttpProperties.Encoding properties;
// 只有一个有参构造器的情况下,参数的值就会从容器中拿
public HttpEncodingAutoConfiguration(HttpProperties properties) {
this.properties = properties.getEncoding();
}

// 给容器中添加一个组件,让这个组件在某些值需要从properties中获取
@Bean
@ConditionalOnMissingBean
public CharacterEncodingFilter characterEncodingFilter() {
CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
filter.setEncoding(this.properties.getCharset().name());
filter.setForceRequestEncoding(this.properties.shouldForce(Type.REQUEST));
filter.setForceResponseEncoding(this.properties.shouldForce(Type.RESPONSE));
return filter;
}

@Bean
public LocaleCharsetMappingsCustomizer localeCharsetMappingsCustomizer() {
return new LocaleCharsetMappingsCustomizer(this.properties);
}

private static class LocaleCharsetMappingsCustomizer
implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory>, Ordered {

private final HttpProperties.Encoding properties;

LocaleCharsetMappingsCustomizer(HttpProperties.Encoding properties) {
this.properties = properties;
}

@Override
public void customize(ConfigurableServletWebServerFactory factory) {
if (this.properties.getMapping() != null) {
factory.setLocaleCharsetMappings(this.properties.getMapping());
}
}

@Override
public int getOrder() {
return 0;
}
}
}

一句话总结:根据当前不同的条件判断,决定这个配置类是否生效!

  • 一旦这个配置类生效;这个配置类就会给容器中添加各种组件;

  • 这些组件的属性是从对应的properties类中获取的,这些类里面的每一个属性又是和配置文件绑定的;

  • 所有在配置文件中能配置的属性都是在xxxxProperties类中封装着;

  • 配置文件能配置什么就可以参照某个功能对应的这个属性类

  • 去配置类中可以查看指定的前缀(prefix)!

这就是自动装配的原理!

2. 精髓分析

  • SpringBoot启动会加载大量的自动配置类
  • 我们看需要的功能有没有在SpringBoot中默认写好的配置类当中
    • 再来看这个自动配置类中到底配置了哪些组件(只要我们用的组件存在其中,我们就不需要手动再配置了)
  • 给容器中自动配置类添加组件的时候,会从properties类中获取某些属性。我们只需要在配置文件中制定这些属性的值即可!
    • xxxxAutoConfiguration : 给容器中添加配置,从xxxProperties读取对应配置的值
    • xxxProperties : 类中的属性就是能配置的选项

3. @Conditional

  • 了解完自动装配的原理后,我们来关注一个细节问题,自动配置类必须在一定的条件下才能生效;

@Conditional派生注解(Spring注解版原生的@Conditional作用)

  • 作用:必须是@Conditional指定的条件成立,才给容器中添加组件,配置配里面的所有内容才生效;
  • 那么多的自动配置类,必须在一定的条件下才能生效;也就是说,我们加载了这么多的配置类,但不是所有的都生效了。
  • 怎么知道哪些自动配置类生效?
    • 可以通过启用 debug=true属性;来让控制台打印自动配置报告,这样我们就可以很方便的知道哪些自动配置类生效;

4. 配置类日志

1
2
#开启springboot的调试类
debug = true

级别:

  • Positive matches:(自动配置类启用的:正匹配)

  • Negative matches:(没有启动,没有匹配成功的自动配置类:负匹配)

  • Unconditional classes: (没有条件的类)

打赏
  • 版权声明: 本博客所有文章除特别声明外,均采用 Apache License 2.0 许可协议。转载请注明出处!
  • © 2019-2022 Zhuuu
  • PV: UV:

请我喝杯咖啡吧~

支付宝
微信