SpringBoot自动配置原理

关于自动配置原理

一、按需开启自动配置项
文件里面写死了springboot一启动就要给容器加载的所有配置类
spring-boot-autoconfigure-2.4.3.jar/spring.factories中,共130个xxxAutoConfiguration组件
虽然130个场景的所有自动配置在启动时默认全部加载
按照@ConditionalOnxxx()条件装配规则,最终会按需配置

二、修改默认配置 分析org.springframework.boot.autoconfigure.web.servlet包下
看MultipartAutoConfiguration源码
@Bean(name = {"multipartResolver"})
@ConditionalOnMissingBean({MultipartResolver.class})
public StandardServletMultipartResolver multipartResolver() {
  StandardServletMultipartResolver multipartResolver = new StandardServletMultipartResolver();
  multipartResolver.setResolveLazily(this.multipartProperties.isResolveLazily());
  return multipartResolver;
}
由以上源码可知:当容器中没有MultipartResolver类型组件时,
会自动配置一个标准名为multipartResolver的MultipartResolver类型组件


看DispatcherServletAutoConfiguration源码,当用户自定义一个名字不叫multipartResolver的MultipartResolver类型的组件时,
会修改之前默认配置的标准名为multipartResolver的MultipartResolver类型组件
@Bean
@ConditionalOnBean({MultipartResolver.class})  //容器中有MultipartResolver类型的组件
@ConditionalOnMissingBean(name = {"multipartResolver"}) //容器中没有名为multipartResolver的组件
public MultipartResolver multipartResolver(MultipartResolver resolver) {
    //当满足上面两个条件(比如容器中出现了一个用户自定义的MultipartResolver类型的组件,组件名为myResolve,
    //则当此方法调用时,Springboot会在容器中找到这个名为myResolve的组件,赋给参数对象resolver,
    //最后方法返回的仍然是用户自定义的组件,只是这个组件的组件名变为了multipartResolver(方法名)
    return resolver;
}
结论:通过上面两处源码的分析可知:最开始容器里是自动配置了一个标准文件上传解析器的(名为multipartResolver的MultipartResolver类型组件),
     当用户自定义了一个MultipartResolver类型的组件,但是用户并没有将组件名按规则命名为multipartResolver时,
     底层会将用户自定义的组件通过以上方法,将组件名更改为multipartResolver,保证了组件名的规范
@Bean
@ConditionalOnMissingBean  //容器中不存在characterEncodingFilter组件时,底层就执行组件方法,将创建的组件添加到容器中
public CharacterEncodingFilter characterEncodingFilter() {...}
结论:SpringBoot默认会在底层配好所有的组件。但是如果用户自己配置了以用户的优先

 




三、配置绑定(属性)
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties({XXXProperties.class})
public class A{}

@ConfigurationProperties(prefix = "spring.mvc")
public class XXXProperties {}
结论:XXXProperties和application.properties配置文件中前缀为“spring.mvc”的属性完成了配置绑定,
对application.properties配置文件中前缀为“spring.mvc”的属性值进行修改时,配置类A中调用XXXProperties对象的属性,可以获取到配置文件修改后的属性值
@EnableConfigurationProperties({XXXProperties.class})
@ConfigurationProperties(prefix = "spring.mvc")

这两个注解配合使用起到的作用:
1.使XXXProperties这个类开启了与配置文件中指定属性的绑定
2.将XXXProperties类型的组件自动注册到容器中



总结:
    1.SpringBoot先加载所有的自动配置类 org.springframework.boot.autoconfigure包下及其所有子包下的xxxAutoConfiguration类
    2.每个自动配置类按照@ConditionalOnxxx()条件进行生效,默认都会绑定配置文件指定的值
        xxxProperties里面拿。xxxProperties和application.properties配置文件进行了绑定
    3.生效的配置类就会给容器中装配很多的组件
    4.只要容器中有了这些组件,相当于这些功能也就有了
    5.定制化配置:
        方式一:用户直接自己@Bean替换底层的组件
        方式二:用户去看这个组件底层是获取的配置文件的什么值就去修改

xxxAutoConfiguration  ---> 组件  ---> xxxProperties  ---> application.properties
 
最佳实践
一.引入场景依赖
  https://docs.spring.io/spring-boot/docs/2.4.3/reference/html/using-spring-boot.html#using-boot-starter
二.查看SpringBoot为我们自动配置了哪些(选做)
第一种:自己找到源码分析,看看引入的场景对应的自动配置是否生效了
        位置:spring-boot-autoconfigure-2.4.3.jar

第二种:在application.properties配置文件中,加上debug=true来开启自动配置报告
Positive matches:表示生效的自动配置
Negative matches:表示不生效的自动配置

三.是否需要修改
1.参照文档修改配置项
1.查看官方文档 https://docs.spring.io/spring-boot/docs/2.4.3/reference/html/appendix-application-properties.html#common-application-properties

2.自己分析: xxxProperties类绑定了配置文件中的哪些属性

2.自定义加入或者替换组件
@Bean @Component
3.自定义器
xxxCustomizer
 

 

posted @ 2021-03-12 01:20  dog_IT  阅读(144)  评论(0编辑  收藏  举报