相比于Spring MVC,Spring Boot省去了繁瑣的配置,提供了大部分場景下的默認(rèn)配置,用戶可以在不做任何配置的情況下使用Spring Boot框架進行開發(fā)。如果默認(rèn)的參數(shù)并不能滿足用戶的需求,也只需創(chuàng)建一個配置文件并加上自定義的配置。Spring Boot的主導(dǎo)思想,想必大家也并不陌生,即:約定優(yōu)于配置。
本文將簡要介紹Spring Boot的自動配置原理,以及自動配置不能滿足要求時,如何自定義配置。
一、Spring Boot的自動配置
Spring Boot之所以能做到自動配置,主要靠的是@EnableAutoConfiguration注解。這個注解集成于程序啟動類注解@SpringBootApplication中。
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
excludeFilters = {@Filter(
type = FilterType.CUSTOM,
classes = {TypeExcludeFilter.class}
), @Filter(
type = FilterType.CUSTOM,
classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
...
}
查看@EnableAutoConfiguration的源碼,發(fā)現(xiàn)兩個主要注解:@AutoConfigurationPackage和@Import。
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class<?>[] exclude() default {};
String[] excludeName() default {};
}
查看@AutoConfigurationPackage注解,發(fā)現(xiàn)也使用了@Import注解,所以有必要先搞懂這個注解的作用。這里推薦一篇博文,感興趣的朋友可以看一下。
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import({AutoConfigurationPackages.Registrar.class})
public @interface AutoConfigurationPackage {
String[] basePackages() default {};
Class<?>[] basePackageClasses() default {};
}
回到主題,@EnableAutoConfiguration中@Import注解通過引入ImportSelector實現(xiàn)類的方式將依賴中的默認(rèn)配置加載到容器中。AutoConfigurationImportSelector類的具體內(nèi)容在這里不做分析,這個過程簡而言之就是:
查看Jar包中META-INF/spring.factories文件,獲取其中EnableAutoConfiguration配置的value值。value值是由多個url組成,一個url表示一個配置類的全類名。然后通過@Import注解導(dǎo)入這些配置類。
@AutoConfigurationPackage中的@Import是通過引入ImportBeanDefinitionRegistrar實現(xiàn)類方式將各種組件和配置引入Spring容器的。簡而言之,就是將標(biāo)注了該注解的類所在的package設(shè)置成為自動配置package,這樣主程序所在的包及其子包中的組件都能夠被掃描到Spring容器中。
案例
下面將通過Tomcat端口配置舉例,版本是spring-boot-actuator-autoconfigure-2.4.2.jar。解壓之后打開META-INF/spring.factoryies文件,發(fā)現(xiàn)org.springframework.boot.autoconfigure.EnableAutoConfiguration配置中如下配置類:
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
...
org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration,\
...
查看該配置類源碼:
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(ServerProperties.class)
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
@ConditionalOnClass(CharacterEncodingFilter.class)
@ConditionalOnProperty(prefix = "server.servlet.encoding", value = "enabled", matchIfMissing = true)
public class HttpEncodingAutoConfiguration {
...
}
我們重點關(guān)注@EnableConfigurationProperties(ServerProperties.class),這個注解的作用是使某個被@ConfigurationProperties標(biāo)注的類生效,這里指的就是ServerProperties類,我們查看ServerProperties類的源碼:
@ConfigurationProperties(prefix = "server", ignoreUnknownFields = true)
public class ServerProperties {
/**
* Server HTTP port.
*/
private Integer port;
/**
* Network address to which the server should bind.
*/
private InetAddress address;
...
}
順便提一句,@ConfigurationProperties是springboot提供讀取配置文件的一個注解,它支持屬性文件和bean的映射,一般和@component配合使用,不然容器無法獲取。如果單獨使用@ConfigurationProperties,需要結(jié)合@EnableConfigurationProperties(ServerProperties.class)將其注冊到spring容器中。
prefix = "server"表示該配置使用server前綴,和屬性port結(jié)合起來就是:server.port。我們都知道Tomcat的默認(rèn)端口是8080,那么這個參數(shù)又是在哪里配置的呢?答案是META-INF/spring-configuration-metadata.json。
{
"name": "server.port",
"defaultValue": 8080
}
可以看到文件中有這么一條配置,這就是我們需要的server.port = 8080。
二、自定義配置
學(xué)習(xí)完以上內(nèi)容,想要自定義配置就簡單多了,還是以Tomcat為例,如果我想將端口改為8081,只需在application.properties文件中加上:
server.port = 8081
至于為什么最終生效的是server.port = 8081而非server.port = 8080,就要提到Spring Boot中的配置優(yōu)先級了,Spring Boot會按照從上到下的順序加載:
- 命令行參數(shù);
- 來自 java:comp/env 的 JNDI 屬性;
- Java 系統(tǒng)屬性(System.getProperties()) ;
- 操作系統(tǒng)環(huán)境變量;
- RandomValuePropertySource 配置的 random.*屬性值;
- jar 包外部的 application-{profile}.properties 或 application.yml(帶 spring.profile)配置文件;
- jar 包內(nèi)部的 application-{profile}.properties 或 application.ym(帶 spring.profile)配置文件;
- jar 包外部的 application.properties 或 application.yml(不帶 spring.profile)配置文件;
- jar 包內(nèi)部的 application.properties 或 application.ym(不帶 spring.profile)配置文件;
- @Configuration 注解類上的@PropertySource;
- 通過 SpringApplication.setDefaultProperties 指定的默認(rèn)屬性。
參考:文章來源:http://www.zghlxwxcb.cn/news/detail-434191.html
《深入淺出Spring Boot 2.x》文章來源地址http://www.zghlxwxcb.cn/news/detail-434191.html
到了這里,關(guān)于Spring Boot的自動配置與自定義配置(附配置優(yōu)先級表)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!