SpringBoot外部化配置使用Plus版 (2)

在使用application.properties时,可以同时在四个位置放置配置,配置的优先级就是上面罗列时显示的优先级。同样的配置,优先级高的生效,优先级低的忽略。

profiles引入的配置,也准守同样的优先级规则

命令行配置具有最高优先级

有些配置不能使用@PropertySource的方式进行注入,比如日志的配置。

如果一个配置类使用了@ConfigurationProperties,然后字段使用了@Value,@ConfigurationProperties先被处理,@Value后被处理。

源码简读

SpringBoot读取application.properties配置

查看org.springframework.boot.context.config.ConfigFileApplicationListener的源码

public class ConfigFileApplicationListener implements EnvironmentPostProcessor, SmartApplicationListener, Ordered { // Note the order is from least to most specific (last one wins) // 默认检索配置文件的路径,优先级越来越高, // 可以通过 spring.config.location重新指定,要早于当前类执行时配置好 private static final String DEFAULT_SEARCH_LOCATIONS = "classpath:/,classpath:/config/,file:./,file:./config/"; // 默认的配置名,可以通过命令行配置--spring.config.name=xxx来重新指定 // 不通过命令行也可以通过其他方式,环境变量这些。 private static final String DEFAULT_NAMES = "application"; private class Loader { // 找到配置的路径 private Set<String> getSearchLocations() { if (this.environment.containsProperty(CONFIG_LOCATION_PROPERTY)) { return getSearchLocations(CONFIG_LOCATION_PROPERTY); } Set<String> locations = getSearchLocations(CONFIG_ADDITIONAL_LOCATION_PROPERTY); locations.addAll( asResolvedSet(ConfigFileApplicationListener.this.searchLocations, DEFAULT_SEARCH_LOCATIONS)); return locations; } // 解析成Set private Set<String> asResolvedSet(String value, String fallback) { List<String> list = Arrays.asList(StringUtils.trimArrayElements(StringUtils.commaDelimitedListToStringArray( (value != null) ? this.environment.resolvePlaceholders(value) : fallback))); // 这里会做一个反转,也就是配置的路径中,放在后面的优先级越高 Collections.reverse(list); return new LinkedHashSet<>(list); } private Set<String> getSearchNames() { if (this.environment.containsProperty(CONFIG_NAME_PROPERTY)) { String property = this.environment.getProperty(CONFIG_NAME_PROPERTY); return asResolvedSet(property, null); } return asResolvedSet(ConfigFileApplicationListener.this.names, DEFAULT_NAMES); } } }

命令行的配置具有最高优先级

protected void configurePropertySources(ConfigurableEnvironment environment, String[] args) { MutablePropertySources sources = environment.getPropertySources(); if (this.defaultProperties != null && !this.defaultProperties.isEmpty()) { sources.addLast(new MapPropertySource("defaultProperties", this.defaultProperties)); } // 支持从命令行添加属性以及存在参数时 if (this.addCommandLineProperties && args.length > 0) { String name = CommandLinePropertySource.COMMAND_LINE_PROPERTY_SOURCE_NAME; // 这里是看下是不是存在同名的配置了 if (sources.contains(name)) { PropertySource<?> source = sources.get(name); CompositePropertySource composite = new CompositePropertySource(name); composite.addPropertySource( new SimpleCommandLinePropertySource("springApplicationCommandLineArgs", args)); composite.addPropertySource(source); sources.replace(name, composite); } else { // 直接添加,并且是添加到第一个位置,具有最高优先级 sources.addFirst(new SimpleCommandLinePropertySource(args)); } } }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyydyg.html