关于自动配置原理
一、按需开启自动配置项
文件里面写死了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