SpringBoot---自动配置【快乐的源码】
6、自动配置
a)、自动包加载规则
分析SpringBoot底层
首先来到主程序中找到SpringBoot注解@SpringBootApplication,进入源码,可以明显地发现这个注解是由
@SpringBootConfiguration @EnableAutoConfiguration @ComponentScan( excludeFilters = {@Filter( type = FilterType.CUSTOM, classes = {TypeExcludeFilter.class} ), @Filter( type = FilterType.CUSTOM, classes = {AutoConfigurationExcludeFilter.class} )} ) public @interface SpringBootApplication {}
这三个合成的,见过的就是一个 @CompentScan组件扫描。
进入@SpringBootConfiguration,可以发现
@Configuration @Indexed public @interface SpringBootConfiguration {
他是一个配置类。这样也能说明主程序类是一个配置类,暂时知道他是配置类就够了
进入@EnableAutoConfiguration注解源码里,这个注解完成了很多工作
@AutoConfigurationPackage @Import({AutoConfigurationImportSelector.class}) public @interface EnableAutoConfiguration {
进入后发现,第一个注解翻译过来是自动配置包,进入他的源码
@Import({Registrar.class})
public @interface AutoConfigurationPackage {
发现他引入了一个注册类组件
进入这个类的源代码中发现,这是一个静态加载类。
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) { AutoConfigurationPackages.register(registry, (String[])(new AutoConfigurationPackages.PackageImports(metadata)).getPackageNames().toArray(new String[0])); }
在里面由new AutoConfigurationPackages.PackageImports(metadata)).getPackageNames().toArray(new String[0])这一句把注册主程序类的包名拿到放进数组里最后返回。这样就拿到了该在程序启动时加载的包和进行组件扫描和其他工作
b)、初始加载自动配置
在刚才@EnableAutoConfiguration注解源码里,第一个注解完成了自动包加载
@AutoConfigurationPackage @Import({AutoConfigurationImportSelector.class}) public @interface EnableAutoConfiguration {
在第二个 引入的类组件中,这个方法里面
public String[] selectImports(AnnotationMetadata annotationMetadata) { if (!this.isEnabled(annotationMetadata)) { return NO_IMPORTS; } else { AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(annotationMetadata); return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations()); } }
使用这个方法查询META文件夹中什么东西,主要发挥作用的是getAutoConfigurationEntry,进入它的源码
protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) { if (!this.isEnabled(annotationMetadata)) { return EMPTY_ENTRY; } else { AnnotationAttributes attributes = this.getAttributes(annotationMetadata); List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes); configurations = this.removeDuplicates(configurations); Set<String> exclusions = this.getExclusions(annotationMetadata, attributes); this.checkExcludedClasses(configurations, exclusions); configurations.removeAll(exclusions); configurations = this.getConfigurationClassFilter().filter(configurations); this.fireAutoConfigurationImportEvents(configurations, exclusions); return new AutoConfigurationImportSelector.AutoConfigurationEntry(configurations, exclusions); } }
发现方法内多次对configurations进行了操作,再继续往下看,发现这个对象是getCandidateConfigurations这个方法拿到的,点进去
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) { List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader()); Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct."); return configurations; }
在里面有 META-INF/spring.factories.,这个就是configurations的来源,这个文件在spring-boot-autoconfigure-2.6.1.jar里面,它里面记载了程序实现过程中需要加载的组件【配置类】,但实际上是不会有这么多组件,
在spring.factories中
里面写死了SpringBoot加载过程中需要的配置类,127个,实际上不会加载这么多组件,可以通过按需配置让SpringBoot 加载配置类,在很多配置类里面有这个 注解@ConditionalOnClass即在有什么类的前提下才会加载特定组件
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\
org.springframework.boot.autoconfigure.context.LifecycleAutoConfiguration,\
org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\
org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,\
org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRestClientAutoConfiguration,\
org.springframework.boot.autoconfigure.data.jdbc.JdbcRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.r2dbc.R2dbcDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.r2dbc.R2dbcRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisReactiveAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration,\
org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientAutoConfiguration,\
org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\
org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration,\
org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration,\
org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration,\
org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration,\
org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration,\
org.springframework.boot.autoconfigure.hazelcast.HazelcastJpaDependencyAutoConfiguration,\
org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration,\
org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration,\
org.springframework.boot.autoconfigure.influx.InfluxDbAutoConfiguration,\
org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration,\
org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration,\
org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.JndiDataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.XADataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration,\
org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.JndiConnectionFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.artemis.ArtemisAutoConfiguration,\
org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration,\
org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration,\
org.springframework.boot.autoconfigure.jsonb.JsonbAutoConfiguration,\
org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration,\
org.springframework.boot.autoconfigure.availability.ApplicationAvailabilityAutoConfiguration,\
org.springframework.boot.autoconfigure.ldap.embedded.EmbeddedLdapAutoConfiguration,\
org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration,\
org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration,\
org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration,\
org.springframework.boot.autoconfigure.mail.MailSenderValidatorAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration,\
org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration,\
org.springframework.boot.autoconfigure.neo4j.Neo4jAutoConfiguration,\
org.springframework.boot.autoconfigure.netty.NettyAutoConfiguration,\
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\
org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration,\
org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration,\
org.springframework.boot.autoconfigure.r2dbc.R2dbcTransactionManagerAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketMessagingAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketRequesterAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketServerAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketStrategiesAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfiguration,\
org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.reactive.ReactiveUserDetailsServiceAutoConfiguration,\
org.springframework.boot.autoconfigure.security.rsocket.RSocketSecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.saml2.Saml2RelyingPartyAutoConfiguration,\
org.springframework.boot.autoconfigure.sendgrid.SendGridAutoConfiguration,\
org.springframework.boot.autoconfigure.session.SessionAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.client.reactive.ReactiveOAuth2ClientAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.resource.reactive.ReactiveOAuth2ResourceServerAutoConfiguration,\
org.springframework.boot.autoconfigure.solr.SolrAutoConfiguration,\
org.springframework.boot.autoconfigure.sql.init.SqlInitializationAutoConfiguration,\
org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration,\
org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration,\
org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration,\
org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration,\
org.springframework.boot.autoconfigure.transaction.jta.JtaAutoConfiguration,\
org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration,\
org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.ReactiveMultipartAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.WebSessionIdResolverAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.error.ErrorWebFluxAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.function.client.ClientHttpConnectorAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.reactive.WebSocketReactiveAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.servlet.WebSocketServletAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.servlet.WebSocketMessagingAutoConfiguration,\
org.springframework.boot.autoconfigure.webservices.WebServicesAutoConfiguration,\
org.springframework.boot.autoconfigure.webservices.client.WebServiceTemplateAutoConfiguration
c)、自动配置流程
了解SpringBoot具体场景启动时的自动配置过程,以web为例
首先找到spring-boot-autoconfigure-2.6.1.jar
\org\springframework\boot\autoconfigure\web\servlet\DispatcherServletAutoConfiguration.class
来到DiapatcherServlerAutoConfiguration
先看到
//声明自己是一个配置类 @Configuration( proxyBeanMethods = false ) //查看项目场景是不是原生servlet,当前项目是用的原生的servlet,所以符合 @ConditionalOnWebApplication( type = Type.SERVLET ) //当前项目中有没有DiapacherServlet这个类,只要引入了SpringBoot就有,所以符合 @ConditionalOnClass({DispatcherServlet.class}) //在ServletWebServerFactoryAutoConfiguration配置完成后再进行配置 @AutoConfigureAfter({ServletWebServerFactoryAutoConfiguration.class}) public class DispatcherServletAutoConfiguration {}
上面发现条件都符合就可以进入类里面观察方法具体做了哪些功能
在类里面发现还有一个类
//说它是一个配置类 @Configuration( proxyBeanMethods = false ) //当前项目有没有DispatcherServletRegistrationCondition这个类,是有的,符合 @Conditional({DispatcherServletAutoConfiguration.DispatcherServletRegistrationCondition.class}) //当前项目有没有ServletRegistration,这个类只要引入了tomcat配置,就有 @ConditionalOnClass({ServletRegistration.class}) //将WebMvcProperties注册为组件开启配置绑定功能 @EnableConfigurationProperties({WebMvcProperties.class}) //引入DispatcherServletConfiguration类 @Import({DispatcherServletAutoConfiguration.DispatcherServletConfiguration.class}) protected static class DispatcherServletRegistrationConfiguration {}
在上面看到@EnableConfigurationProperties将WebMvcProperties开启配置绑定,在WebMvcProperties中
//将application.propertis文件中前缀为spring.mvc的配置跟这个类里面的属性进行绑定,在后面需要绑定可以根据这里面的属性名进行设置值 @ConfigurationProperties( prefix = "spring.mvc" ) public class WebMvcProperties {}
上面DispatcherServletRegistrationConfiguration类前面的条件都满足,继续看那个配置类
在DispatcherServletRegistrationConfiguration里面,注册一个组件名dispatcherServletRegistration为这个的组件
判断项目里有没有名字叫dispatcherServlet或者是类型是DispatcherServlet类型的组件,很明显有
protected static class DispatcherServletRegistrationConfiguration { protected DispatcherServletRegistrationConfiguration() { } @Bean( name = {"dispatcherServletRegistration"} ) @ConditionalOnBean( value = {DispatcherServlet.class}, name = {"dispatcherServlet"} ) //在这个方法里就是SpringBoot自己创建了一个DispatcherServletRegistrationBean对象,并对各种属性设置好值,最后返回DispatcherServletRegistrationBean这个对象。 所以说这个其实就是底层做好了DispatcherServlet配置 public DispatcherServletRegistrationBean dispatcherServletRegistration(DispatcherServlet dispatcherServlet, WebMvcProperties webMvcProperties, ObjectProvider<MultipartConfigElement> multipartConfig) { DispatcherServletRegistrationBean registration = new DispatcherServletRegistrationBean(dispatcherServlet, webMvcProperties.getServlet().getPath()); registration.setName("dispatcherServlet"); registration.setLoadOnStartup(webMvcProperties.getServlet().getLoadOnStartup()); multipartConfig.ifAvailable(registration::setMultipartConfig); return registration; } }
在下面还有一个配置类
//声明自己是一个配置类 @Configuration( proxyBeanMethods = false ) //有没有DefaultDispatcherServletCondition这个类,有,就在这个自动配置类【DispatcherServletAutoConfiguration】里面 @Conditional({DispatcherServletAutoConfiguration.DefaultDispatcherServletCondition.class}) //有没有ServletRegistration这个组件,引入了tomcat依赖就有 @ConditionalOnClass({ServletRegistration.class}) //声明类WebMvcProperties为组件并且开启配置绑定 @EnableConfigurationProperties({WebMvcProperties.class}) //都通过,现在可以看底下的源码 protected static class DispatcherServletConfiguration { protected DispatcherServletConfiguration() { } //注册一个名叫dispatcherServlet的组件 @Bean( name = {"dispatcherServlet"} ) //在这个方法里手动new了一个DispatcherServlet对象并设置好了各种属性值,把本来需要配置文件做的事情在底层中已经设置好了,省去了自己设置的功夫,最后把dispatcherServlet对象返回 public DispatcherServlet dispatcherServlet(WebMvcProperties webMvcProperties) { DispatcherServlet dispatcherServlet = new DispatcherServlet(); dispatcherServlet.setDispatchOptionsRequest(webMvcProperties.isDispatchOptionsRequest()); dispatcherServlet.setDispatchTraceRequest(webMvcProperties.isDispatchTraceRequest()); dispatcherServlet.setThrowExceptionIfNoHandlerFound(webMvcProperties.isThrowExceptionIfNoHandlerFound()); dispatcherServlet.setPublishEvents(webMvcProperties.isPublishRequestHandledEvents()); dispatcherServlet.setEnableLoggingRequestDetails(webMvcProperties.isLogRequestDetails()); return dispatcherServlet; } @Bean //有没有MultipartResolver这个类型的组件 @ConditionalOnBean({MultipartResolver.class}) //当前项目中不存在一个名叫multipartResolver的MultipartResolver类型的组件 这一步就是针对在自己设置文件上传MultipartResolver组件时命名不规范,当SpringBoot拿到这个组件时,名字不规范,他就在这里用下面的方法处理,把你不规范的用这个规范的替换掉,你那个不规范的实际上还在IOC容器中,只是在使用时不会被用到。 @ConditionalOnMissingBean( name = {"multipartResolver"} ) 在MVC时,文件上传解析器的id必须叫multipartResolver //这个方法就是当你调用这个方法后,他被标注了@Bean注解,他有参数就会自动去IOC容器中找MultipartResolver类型的组件,这个组件就是你注册的那个不规范的id,然后在方法里把你注册的这个文件上传解析器以方法名multipartResolver加到IOC容器中。这样MultipartResolver的名字就又叫multipartResolver public MultipartResolver multipartResolver(MultipartResolver resolver) { return resolver; } }
第二个初始化有关的自动配置类HttpEncodingAutoConfiguration
//声明自己是一个配置类 @Configuration( proxyBeanMethods = false ) //注册组件并开启配置绑定 @EnableConfigurationProperties({ServerProperties.class}) //判断是不是原生Servlet的项目,是的 @ConditionalOnWebApplication( type = Type.SERVLET ) //判断当前有没有这个CharacterEncodingFilter,只要有SpringMvc的依赖,肯定就有 @ConditionalOnClass({CharacterEncodingFilter.class}) //有没有配置项前缀为server.servlet.encoding,值是enabled的,最后一个配置说明默认是有的 @ConditionalOnProperty( prefix = "server.servlet.encoding", value = {"enabled"}, matchIfMissing = true ) //可以去看内部实现了 public class HttpEncodingAutoConfiguration {}
HttpEncodingAutoConfiguration类里面
public class HttpEncodingAutoConfiguration { //定义的一个Encoding类型的属性,这个类型在CharacterEncodingFilter里面有,之前Mvc用过 private final Encoding properties; //规定属性值从哪里获取到 public HttpEncodingAutoConfiguration(ServerProperties properties) { this.properties = properties.getServlet().getEncoding(); } //如果在当前容器中没有CharacterEncodingFilter类型的组件,那就执行下面的方法给你配置一个 //这个就是说即使按需开启自动配置,也是以用户配置的优先 @Bean @ConditionalOnMissingBean public CharacterEncodingFilter characterEncodingFilter() { CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter(); filter.setEncoding(this.properties.getCharset().name()); filter.setForceRequestEncoding(this.properties.shouldForce(org.springframework.boot.web.servlet.server.Encoding.Type.REQUEST)); filter.setForceResponseEncoding(this.properties.shouldForce(org.springframework.boot.web.servlet.server.Encoding.Type.RESPONSE)); return filter; } @Bean public HttpEncodingAutoConfiguration.LocaleCharsetMappingsCustomizer localeCharsetMappingsCustomizer() { return new HttpEncodingAutoConfiguration.LocaleCharsetMappingsCustomizer(this.properties); } static class LocaleCharsetMappingsCustomizer implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory>, Ordered { private final Encoding properties; LocaleCharsetMappingsCustomizer(Encoding properties) { this.properties = properties; } public void customize(ConfigurableServletWebServerFactory factory) { if (this.properties.getMapping() != null) { factory.setLocaleCharsetMappings(this.properties.getMapping()); } } public int getOrder() { return 0; } } }
总结:
1、SpringBoot加载所有自动配置类
2、每个自动配置类按照条件加载生效
3、如果生效,配置类就会给容器中注册很多组件,这样功能就得以实现
4、用户【开发人员】配置了功能,就以用户的配置优先
5、而且很多自动配置类上面都应用了注解@EnableConfigurationProperties,将类属性和配置文件进行绑定,当对于自动配置的内容不满意时,可以自己在配置文件中进行修改或者想做到纯代码开发那就直接@Bean然后重写底层的方法,想换什么换什么
XXXAutoConfiguration -->>组件 -->> XXXproperties -->> application.properties,获取值的顺序
当需要修改自动配项时,要么去官网找Application Properties里面的不同场景,要么就直接底层找XXXAutoConfiguration,找@EnableConfigurationProperties注解,进入里面绑定的类的源码里查看前缀,然后自己在application.properties里面修改想修改的内容
在使用中:
-
当想要进行某些场景开发,那就首先引入场景依赖,spring-boot-starter-XXX
-
在场景开发过程中,需要查看某些自动配置
-
一个是自己去spring-boot-autoconfigure-2.6.1.jar这个依赖里面找对应的引入的场景的自动配置类,看看都配置了什么
-
另一个直接在application.properties配置文件中写上 debug=true,就能在输出中看见,有哪些自动配置启动生效了,那些没生效,因为什么 Negative matches:不生效的 Positive matches: 生效了的
-
假如在开发时对有些配置不喜欢,想要修改配置:
-
要么就在官网里面找ApplicationProperties里面找自己开发的那个场景相应的配置或者自己去spring-boot-autoconfigure-2.6.1.jar依赖里面找对应场景的自动配置类,看都有哪些配置属性和配置文件绑定了
-
要么就自己@Bean给容器中添加底层组件,用户有的,会优先用户的。
-
例如现在想要修改SpringBoot启动时的动画。找到官网的配置项里面的coreproperties,在里面有一个spring.banner,在这个配置里面对应设置动画的就是[
spring.banner.image.location],配置项后面也有解释说什么可以用,在配置文件中设置他的路径,一般这个图片和配置文件放在同一个目录下

浙公网安备 33010602011771号