IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> SpringBoot---自动配置【快乐的源码环节】 -> 正文阅读

[Java知识库]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 {}

类里面

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里面修改想修改的内容

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-12-07 11:53:51  更:2021-12-07 11:56:04 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 6:49:17-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码