1、ConfigurationProperties
将配置文件中的多行配置,映射到一个Java类里的若干属性。
配置文件及Java代码
logging:
level:
org.springframework.web: ERROR
com.mkyong: DEBUG
email: test@mkyong.com
thread-pool: 10
app:
menus:
- title: Home
name: Home
path: /
- title: Login
name: Login
path: /login
compiler:
timeout: 5
output-folder: /temp/
error: /error/
@Component
@Validated
@ConfigurationProperties(prefix = "app", ignoreInvalidFields = false, ignoreUnknownFields = false)
public class AppProperties {
//属性略
}
解释
@Validated
和javax.validation.constraints.NotEmpty、javax.validation.constraints.Max、javax.validation.constraints.Min等标准化注解配合使用,如果配置的属性值校验失败,启动SpringBoot时报错。
prefix = “app”
配置文件中以app开头的属性,将被映射到AppProperties对应的属性。
ignoreInvalidFields = false
如果某些属性的值无效,如AppProperties对应的属性为boolean类型你却赋值为123,启动SpringBoot时报错。
ignoreUnknownFields = false
如果某些属性无法映射到AppProperties的任何属性,启动SpringBoot时报错。
2、ConditionalOnProperty
使人想到一句谚语:不见兔子不撒鹰,即只有看见了兔子,才撒开鹰。
@Configuration
@ConditionalOnProperty(prefix = "app", name = "error1")
public class JjkConfig {
// 略
}
如果配置了属性app.error1,则初始化JjkConfig,显然没有配置,启动时可以看到:
JjkConfig:
Did not match:
- @ConditionalOnProperty (app.error1) did not find property 'error1' (OnPropertyCondition)
@Configuration
@ConditionalOnProperty(prefix = "app", name = "error")
public class JjkConfig {
// 略
}
如果配置了属性app.error,则初始化JjkConfig,启动时可以看到:
JjkConfig matched:
- @ConditionalOnProperty (app.error) matched (OnPropertyCondition)
3、从指定的yml文件映射到属性类
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.support.EncodedResource;
import org.springframework.core.io.support.PropertySourceFactory;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;
public class YamlPropertySourceFactory implements PropertySourceFactory {
@Override
public PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException {
Properties propertiesFromYaml = loadYamlIntoProperties(resource);
String sourceName = name != null ? name : resource.getResource().getFilename();
return new PropertiesPropertySource(sourceName, propertiesFromYaml);
}
private Properties loadYamlIntoProperties(EncodedResource resource) throws FileNotFoundException {
try {
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
factory.setResources(resource.getResource());
factory.afterPropertiesSet();
return factory.getObject();
} catch (IllegalStateException e) {
Throwable cause = e.getCause();
if (cause instanceof FileNotFoundException) {
throw (FileNotFoundException) e.getCause();
}
throw e;
}
}
}
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix = "my")
//@ConditionalOnProperty(prefix = "my", name = "name")
@PropertySource(value = "classpath:application-any.yml", factory = YamlPropertySourceFactory.class)
public class CustomizedYmlProperties {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "CustomizedYmlProperties{" +
"name='" + name + '\'' +
'}';
}
}
注意:ConditionalOnProperty注解无效。
4、参考资料
- https://github.com/mkyong/spring-boot/tree/master/externalize-config-properties-yaml
- https://blog.csdn.net/yusimiao/article/details/97622666 (https://github.com/FraserYu/learnings/tree/master/configurationproperties)
- https://www.baeldung.com/configuration-properties-in-spring-boot