SpringBoot 自动配置初探

  • @EnableAutoConfiguration
    • @Import(AutoConfigurationImportSelector.class)
  • selectImports
  • autoConfigurationEntry
  • getCandidateConfigurations
  • loadFactoryNames
  • Jar包下的spring.factories
  • 例子 HttpEncodingAutoConfiguration
    • HttpProperties
  • 总结

springboot的一大特点就是自动配置,本笔记将记录springboot的自动配置是如何实现的。将对源码进行跟踪和分析。
2019年07月31日09:16:31
87160265@qq.com

@EnableAutoConfiguration

当我们看到springboot的启动类的时候,会在上部分看到这个类的注解,其中有一个@EnableAutoConfiguration的注解 AutoConfiguration的出现,告诉我们这个一定和自动 Auto和配置 Configuration 有关。

按住 ctrl进入这个注解,我们可以看见这个注解的源代码,下面截取头部部分。

@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {

@Import(AutoConfigurationImportSelector.class)

这个注解的作用,是利用这个选择器 ...Selector.class来给容器中导入一些组件。

进入这个注解,下拉。我们可以看见在这个类里面有如下这样一个方法。

 @Overridepublic String[] selectImports(AnnotationMetadata annotationMetadata) {...}

meta,一般在计算机中的意思是 元 元数据(Metadata)的元。

这个方法,返回的是字符串数组。

selectImports

我们仔细看源码的返回值:

return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());

利用 StringUtils这个spring的工具类,将一个autoConfigurationEntry.getConfigurations()传回的数据转换成了字符串数组。

autoConfigurationEntry

我们来观察这个autoConfigurationEntry

AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(autoConfigurationMetadata,annotationMetadata);

这个AutoConfigurationEntry类是怎么定义的呢?

protected static class AutoConfigurationEntry {private final List<String> configurations;private final Set<String> exclusions;private AutoConfigurationEntry() {this.configurations = Collections.emptyList();this.exclusions = Collections.emptySet();}

一目了然,AutoConfigurationEntry 里面包含着String类型的集合 List<String> configurations

回到 selectImports这个方法。

这个方法的作用,就是想要获取到这一系列的配置(configurations)

在selectImports这个方法内部

AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(autoConfigurationMetadata,annotationMetadata);

这句话告诉我们,autoConfigurationEntry也就是想要的这些configurations,必须通过 getAutoConfigurationEntry这个方法获取,我们点进来一看,有这样一句话:

List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);

继续点,找到这样一个方法:

getCandidateConfigurations

protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),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;
}

其中,下面这个方法才是最主要的。

List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),getBeanClassLoader());

SpringFactoriesLoader这个类的作用就是扫描所有jar包类路径下的一个文件,在这个类的源码首行。

public final class SpringFactoriesLoader {public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";

"META-INF/spring.factories"就是需要扫描的路径和文件。

那么扫描这个文件的作用是什么?

loadFactoryNames

在上面提及到的 loadFactoryNames这个方法里面,我们可以继续点进去查看。

public static List<String> loadFactoryNames(Class<?> factoryClass, @Nullable ClassLoader classLoader) {String factoryClassName = factoryClass.getName();return loadSpringFactories(classLoader).getOrDefault(factoryClassName, Collections.emptyList());
}

同样,点入 loadSpringFactories(classLoader).getOrDefault(factoryClassName, Collections.emptyList());中的 loadSpringFactories(classLoader)方法。

在这个方法里面,代码的语义可以理解为。

Enumeration<URL> urls = (classLoader != null ?classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
result = new LinkedMultiValueMap<>();while (urls.hasMoreElements()) {URL url = urls.nextElement();UrlResource resource = new UrlResource(url);Properties properties = PropertiesLoaderUtils.loadProperties(resource);for (Map.Entry<?, ?> entry : properties.entrySet()) {String factoryClassName = ((String) entry.getKey()).trim();for (String factoryName : StringUtils.commaDelimitedListToStringArray((String) entry.getValue())) {result.add(factoryClassName, factoryName.trim());}}}

得到这些方法的url,最后将每个方法遍历。

将这些文件的内容整合成一个properties对象。

String factoryClassName = ((String) entry.getKey()).trim();

每一个url都会被获取它的值,最后被加载返回值result中,这个result中,就包含了spring容器中需要的一些组件。

回到getCandidateConfigurations方法。

List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),getBeanClassLoader());

注意看 loadFactoryNames 的第一个入参。 getSpringFactoriesLoaderFactoryClass()点进去之后。

protected Class<?> getSpringFactoriesLoaderFactoryClass() {return EnableAutoConfiguration.class;
}

可以清楚的观察到,EnableAutoConfiguration.class的存在。从properties中获取到EnableAutoConfiguration.class这个类类名对应的值,把他们添加在容器中。

Jar包下的spring.factories

我们可以点开一个jar包,查看里面的内容。
但是查看内容之后,并没有EnableAutoConfiguration这个类对应的值。

再往下看一个jar包 spring-boot-autoconfigure-2.1.6.RELEASE.jar ,点开 spring.factories

我们可以清楚的看到,这个jar包配置了 EnableAutoConfiguration,那么下面的这些组件,都会被自动配置到spring容器中。

回顾一下SpringFactoriesLoader类里面,属性规定了我们要去 "META-INF/spring.factories"jar包类路径下配置所有开启 EnableAutoConfiguration的值,把他们加入到容器当中去。

结合上面 spring.factories文件,这个流程更加的直观。

我们把这个jar包开启自动配置之下的值全部拷在下面。

# 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.cloud.CloudServiceConnectorsAutoConfiguration,\
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\
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.ElasticsearchAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,\
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.Neo4jRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.solr.SolrRepositoriesAutoConfiguration,\
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.jest.JestAutoConfiguration,\
org.springframework.boot.autoconfigure.elasticsearch.rest.RestClientAutoConfiguration,\
org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\
org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration,\
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.groovy.template.GroovyTemplateAutoConfiguration,\
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.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.orm.jpa.HibernateJpaAutoConfiguration,\
org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration,\
org.springframework.boot.autoconfigure.reactor.core.ReactorCoreAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.SecurityRequestMatcherProviderAutoConfiguration,\
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.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.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.ReactiveWebServerFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration,\
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

仔细观察,每一个 xxAutoConfiguration 类都是容器中的自动配置类。都加入到容器中去,使用他们来做更多的自动配置功能。

例子 HttpEncodingAutoConfiguration

在上面 我们可以找到 org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration,\

我们去文件中找到这类。

@Configuration
@EnableConfigurationProperties(HttpProperties.class)
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
@ConditionalOnClass(CharacterEncodingFilter.class)
@ConditionalOnProperty(prefix = "spring.http.encoding", value = "enabled", matchIfMissing = true)
public class HttpEncodingAutoConfiguration {private final HttpProperties.Encoding properties;public HttpEncodingAutoConfiguration(HttpProperties properties) {this.properties = properties.getEncoding();}@Bean@ConditionalOnMissingBeanpublic 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;}@Beanpublic LocaleCharsetMappingsCustomizer localeCharsetMappingsCustomizer() {return new LocaleCharsetMappingsCustomizer(this.properties);}private static class LocaleCharsetMappingsCustomizerimplements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory>, Ordered {private final HttpProperties.Encoding properties;LocaleCharsetMappingsCustomizer(HttpProperties.Encoding properties) {this.properties = properties;}@Overridepublic void customize(ConfigurableServletWebServerFactory factory) {if (this.properties.getMapping() != null) {factory.setLocaleCharsetMappings(this.properties.getMapping());}}@Overridepublic int getOrder() {return 0;}}}

首先是注解的解析:

@Configuration
@EnableConfigurationProperties(HttpProperties.class)
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
@ConditionalOnClass(CharacterEncodingFilter.class)
@ConditionalOnProperty(prefix = "spring.http.encoding", value = "enabled", matchIfMissing = true)
  • @Configuration 表示,这是一个配置类的方式向容器中添加组件 @Bean的注解。
  • @EnableConfigurationProperties(HttpProperties.class)指定启动 HttpProperties.class这个类的ConfigurationProperties功能。
  • @ConditionalOnWebApplication根据当前程序是不是web应用,如果是,则生效。
  • @ConditionalOnClass判断当期项目有没有CharacterEncodingFilter.class的存在。这个是springmvc中解决乱码的过滤器
  • @ConditionalOnProperty判断配置文件中是否存在"spring.http.encoding"的配置,matchIfMissing = true如果不存在,也生效。也就是说,如果在我们的配置文件中,没有 spring.http.encoding.enabled=true那么这个注解也是生效的。

HttpEncodingAutoConfiguration这个自动配置类生效之后,该类会在容器中添加如下两个组件 @Bean

 @Bean@ConditionalOnMissingBeanpublic CharacterEncodingFilter characterEncodingFilter() {
===================================================@Beanpublic LocaleCharsetMappingsCustomizer localeCharsetMappingsCustomizer() {

这些组件的值,也就来自于开头注解中的配置文件。作为容器中的一个bean,程序上下文在执行这个方法的时候,自动将里面的属性赋值。

HttpProperties

源码如下:

@ConfigurationProperties(prefix = "spring.http")
public class HttpProperties {

点进来,我们可以看见 @ConfigurationProperties(prefix = "spring.http")的注解。

这个非常好理解,之前也试过这个注解的使用并那他来和 @Value来区分。

这个注解的意思就是指定了配置文件中这个类属性key的前缀,spring会自动从其中取出这个值并吧上下文中这个bean的属性的值进行绑定。

@ConfigurationProperties支持松绑定

这个类下面的属性,也就基本上对应了配置文件中,根据他指定的前缀能取到什么的值。

所有能在配置文件中配置的属性,都是在XXXProperties的类中封装着。

关于字符过滤器,我们在学习springMVC的时候,这些属性是配置在web.xml中的。迁移过来思考一下,就更容易理解。我们可以观察之前的SSM项目中的配置文件对应着思考一下。

比如在这个类里面,我们就能配置:

public static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;
private Charset charset = DEFAULT_CHARSET;
private Boolean force;
private Boolean forceRequest;
private Boolean forceResponse;

仔细看看,是不是都很熟悉。


总结

以上就是springboot的整个精髓,总结如下

  1. springboot启动会加载大量配置类。
  2. 我们在开发需要某个功能的时候,可以先看看springboot里面有没有已经写好的自动配置类。
  3. 再看看自动配置类里面可以为我们配置哪些组件,如果有,我们的配置文件中就不需要提及。
  4. 容器中自动配置类添加组件的时候,会从 properties 类中获取属性,这些属性都是从配置文件中获取的。因为这两个内容是绑定的。
  5. XXXAutoConfiguration 类是自动配置类,这个类会向spring 容器中配置组件,这些组件的属性是在xxxProperties类里面规定好的。在这个类里面会与配置文件里面的值进行绑定。

SpringBoot 自动配置初探相关推荐

  1. SpringBoot自动配置的原理及实现

    SpringBoot的核心就是自动配置,自动配置是基于条件判断配置Bean 自动配置的源码在spring-boot-autoconfigure-2.2.13.RELEASE SpringBoot运行原 ...

  2. 这样讲 SpringBoot 自动配置原理,你应该能明白了吧

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试资料 作者:你在我家门口 juejin.im/post/5ce5effb ...

  3. 【Spring框架家族】SpringBoot自动配置基本实现

    SpringBoot自动配置-Condition_1 Condition是Spring4.0后引入的条件化配置接口,通过实现Condition接口可以完成有条件的加载相应的Bean @Conditio ...

  4. SpringBoot 自动配置

    Springboot 自动配置 关注 "弋凡"(YiFan)微信公众号吧 记录简单笔记 做你的最爱 Springboot 是什么呐? 我管她是什么,好用就行了啊!!! spring ...

  5. SpringBoot实战之SpringBoot自动配置原理

    www.cnblogs.com/leihuazhe/p- SpringBoot 自动配置主要通过 @EnableAutoConfiguration, @Conditional, @EnableConf ...

  6. SpringBoot | 自动配置原理

    微信公众号:一个优秀的废人.如有问题,请后台留言,反正我也不会听. 前言 这个月过去两天了,这篇文章才跟大家见面,最近比较累,大家见谅下.下班后闲着无聊看了下 SpringBoot 中的自动配置,把我 ...

  7. springboot自动配置的原理_SpringBoot自动配置原理

    SpringBoot的启动入口就是一个非常简单的run方法,这个run方法会加载一个应用所需要的所有资源和配置,最后启动应用. 通过查看run方法的源码,我们发现,run方法首先启动了一个监听器,然后 ...

  8. springboot自动配置的原理_SpringBoot实战:详解SpringBoot自动配置原理

    SpringBoot 自动配置主要通过 @EnableAutoConfiguration, @Conditional, @EnableConfigurationProperties 或者 @Confi ...

  9. SpringBoot 自动配置原理

    创建项目 通过Spring Initialize创建SpringBoot项目 而接下来要说的是关于配置文件的事情.关乎配置文件可以参考官方文档. 对于配置文件来说到底在配置文件里面可以进行配置那些内容 ...

最新文章

  1. 【直播回放】150分钟详解模型压缩理论和实践
  2. “约见”面试官系列之常见面试题第四十四篇之webpack打包原理解析?(建议收藏)
  3. 待熟悉的工具或API清单列表
  4. 您实际上可以通过这些YouTube视频了解GPT-3
  5. vb计算机安装教程,windows10系统安装vb6.0图文教程 Win10攻略
  6. 电视盒子刷鸿蒙系统,当贝市场亲测有效三款获取电视和盒子root权限的工具应用...
  7. 中国伺服电机市场现状调查与投资战略分析报告2022-2028年
  8. Insyde BIOS@G50-80 初探
  9. Visual Studio Qt vs tools 下载教程及加速教程
  10. Spring AOP 的术语
  11. 毕业设计 基于云平台的火灾报警系统设计与实现 - stm32 物联网 单片机 OneNET云平台
  12. 人民网:“2021数字基建论坛”在京召开,共议行业高质量发展
  13. 重温离散数学系列①之什么是证明
  14. 从水果连连看到两条序列比对
  15. 剪视频到底要什么样的电脑配置?
  16. 视频爬虫js逆向——我搜不到密参怎么办
  17. MCP2515驱动程序
  18. 网线线序如何排列,586B与586A的区别
  19. UDS服务基础篇之2F
  20. linux 网络带宽和延时测试

热门文章

  1. python爬取高匿代理IP(再也不用担心会进小黑屋了)
  2. 蚂蚁金服副总谈区块链
  3. 阿里云短信服务(申请与代码)
  4. 【路径规划】(2) A* 算法求解最短路,附python完整代码
  5. codecombat 代码攻略
  6. win服务器系统更新失败怎么办,win10系统更新失败怎么办
  7. 【IOS实用玩机技巧】爱思助手 IPA 签名功能常见问题汇总(iOS上架)
  8. 微信商户平台,开通企业付款到用户零钱功能
  9. 《人生的智慧》-叔本华著[韦启昌-(译)]
  10. 微信官方支付接口配置教程