Spring為我們提供了默認配置機制,從而大大提高了開發效率,讓我們脫離了配置文件的苦海。但是很多初學的同學們可能會疑惑,默認配置機制究竟是怎么實現的呢?
配置類
SpringBoot在spring-boot-autoconfigure
中提供了大量的配置類,如負責配置並初始化tomcat、jetty等的EmbeddedWebServerFactoryCustomizerAutoConfiguration
配置類,自然作為配置類,和我們自己寫的配置類一樣,這個類中也聲明了@Configuration
注解。
@Configuration // <1.1>
@ConditionalOnWebApplication // <2.1>
@EnableConfigurationProperties(ServerProperties.class) // <3.1>
public class EmbeddedWebServerFactoryCustomizerAutoConfiguration {
/**
* Nested configuration if Tomcat is being used.
*/
@Configuration // <1.2>
@ConditionalOnClass({ Tomcat.class, UpgradeProtocol.class })
public static class TomcatWebServerFactoryCustomizerConfiguration {
@Bean
public TomcatWebServerFactoryCustomizer tomcatWebServerFactoryCustomizer(
Environment environment, ServerProperties serverProperties) {
// <3.2>
return new TomcatWebServerFactoryCustomizer(environment, serverProperties);
}
}
/**
* Nested configuration if Jetty is being used.
*/
@Configuration // <1.3>
@ConditionalOnClass({ Server.class, Loader.class, WebAppContext.class })
public static class JettyWebServerFactoryCustomizerConfiguration {
@Bean
public JettyWebServerFactoryCustomizer jettyWebServerFactoryCustomizer(
Environment environment, ServerProperties serverProperties) {
// <3.3>
return new JettyWebServerFactoryCustomizer(environment, serverProperties);
}
}
/**
* Nested configuration if Undertow is being used.
*/
// ... 省略 UndertowWebServerFactoryCustomizerConfiguration 代碼
/**
* Nested configuration if Netty is being used.
*/
// ... 省略 NettyWebServerFactoryCustomizerConfiguration 代碼
}
Springboot是如何知道加載那些自動配置類的呢
在我們通過 SpringApplication#run(Class<?> primarySource, String... args) 方法,啟動 Spring Boot 應用的時候,有個非常重要的組件 SpringFactoriesLoader 類,會讀取 META-INF 目錄下的 spring.factories 文件,獲得每個框架定義的需要自動配置的配置類。spring.factories中指明了主流框架所需的自動配置類。然后根據我們在pom引入的starter來加載對應的配置類
條件注解
Spring Boot 的 condition 包下,提供了大量的條件注解,通過對條件注解的應用使得我們可以只在滿足響應條件的情況下使得某些配置生效。
如代碼中<1.2>@ConditionalOnClass({ Tomcat.class, UpgradeProtocol.class })
便聲明了需要有 tomcat-embed-core 依賴提供的 Tomcat、UpgradeProtocol 依賴類,才能創建內嵌的 Tomcat 服務器。
配置屬性(使我們的配置文件生效)
SpringBoot提供了@ConfigurationProperties
注解用於聲明配置屬性類,不同的前綴(即不同的組件)配置項會有不同的配置屬性類,然后如上文代碼<3.1>@EnableConfigurationProperties(ServerProperties.class)
使得配置屬性類生效,也就是說通過將我們的配置文件映射到對應的配置屬性類,再講配置屬性類傳入到對應的配置類,從而使得我們可以自定義配置。如下為server前綴配置項(tomcat)的配置屬性類。
@ConfigurationProperties(prefix = "server", ignoreUnknownFields = true)
public class ServerProperties
implements EmbeddedServletContainerCustomizer, EnvironmentAware, Ordered {
/**
* Server HTTP port.
*/
private Integer port;
/**
* Context path of the application.
*/
private String contextPath;
// ... 省略其它屬性
}