前言
最近在写框架时遇到需要根据特定配置(可能不存在)加载 bean 的需求,所以就学习了下 Spring 中如何获取配置的几种方式。
Spring 中获取配置的三种方式
通过 @Value 方式动态获取单个配置 通过 @ConfigurationProperties + 前缀方式批量获取配置 通过 Environment 动态获取单个配置
通过 @Value 动态获取单个配置
1.作用
可修饰到任一变量获取,使用较灵活
2.优点
使用简单,且使用关联的链路较短
3.缺点
配置名不能被有效枚举到 每一个配置的使用都需重新定义,使用较为麻烦 项目强依赖配置的定义,配置不存在则会导致项目无法启动4.使用场景
项目强依赖该配置的加载,想要从源头避免因配置缺失导致的未知问题 只想使用少数几个配置5.代码示例
|
1 2 3 4 5 6 7 8 9 10 |
@Configuration public class ConfigByValueAnnotation {
@Value ( "${server.port}" ) private String serverPort;
public String getServerPort() { return serverPort; } } |
6.测试代码
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
@DisplayName ( "multipart get config" ) @SpringBootTest public class MultipartGetConfigTest {
private static final Logger log = LoggerFactory.getLogger(MultipartGetConfigTest. class );
@Autowired private ConfigByValueAnnotation configByValueAnnotation;
@Test public void getByValueAnnotation(){ log.info( "get by @Value, value: {}" , configByValueAnnotation.getServerPort()); } } |
7.测试结果
org.spring.demo.MultipartGetConfigTest : get by @Value, value: 7100
通过@ConfigurationProperties+前缀方式批量获取
1.作用
用于配置类的修饰或批量配置的获取
2.优点
使用配置只需确定 key 的前缀即能使用,有利于批量获取场景的使用 因采用前缀匹配,所以在使用新的相同前缀 key 的配置时无需改动代码3.缺点
使用复杂,需定义配置类或者手动创建 bean 后引入使用 增加新的前缀相同 key 时可能会引入不稳定因素4.使用场景
需要同时使用多前缀相同 key 的配置 期望增加新配置但不修改代码的 properties 注入5.代码示例
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
@Component @ConfigurationProperties (prefix = "server" , ignoreInvalidFields = true ) public class ConfigByConfigurationProperties {
private Integer port;
public Integer getPort() { return port; }
public ConfigByConfigurationProperties setPort(Integer port) { this .port = port; return this ; } } |
|
1 2 3 4 5 6 7 8 9 10 |
@Configuration public class ConfigByConfigurationPropertiesV2 {
@Bean ( "configByValueAnnotationV2" ) @ConfigurationProperties (prefix = "server2" ) public Properties properties(){ return new Properties(); }
} |
6.测试代码
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
@DisplayName ( "multipart get config" ) @SpringBootTest public class MultipartGetConfigTest {
private static final Logger log = LoggerFactory.getLogger(MultipartGetConfigTest. class );
@Autowired private ConfigByConfigurationProperties configByConfigurationProperties;
@Autowired @Qualifier ( "configByValueAnnotationV2" ) private Properties properties;
@Test public void getByConfigurationProperties(){ log.info( "get by @ConfigurationProperties, value: {}" , configByConfigurationProperties.getPort()); log.info( "get by @ConfigurationProperties and manual create bean, value: {}" , properties.getProperty( "port" )); }
} |
7.测试结果
org.spring.demo.MultipartGetConfigTest : get by @ConfigurationProperties, value: 7100
org.spring.demo.MultipartGetConfigTest : get by @ConfigurationProperties and manual create bean, value: 7100
通过 Environment 动态获取单个配置
1.作用
用于动态在程序代码中获取配置,而配置 key 不需提前定义
2.优点
获取的配置的 key 可不提前定义,程序灵活性高 配置 key 可使用枚举统一放置与管理3.缺点
使用较复杂,需继承 Environment 接口形成工具类进行获取 获取 key 对应的枚举与 key 定义分离,value 获取链路较长4.使用场景
只需使用少量的配置 获取配置的 key 无提前定义,需要根据对配置的有无进行灵活使用5.代码示例
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
@Component public class ConfigByEnvironment implements EnvironmentAware {
private static final Logger log = LoggerFactory.getLogger(ConfigByEnvironment. class );
private Environment environment;
public Optional<String> get(String configKey){ String config = environment.getProperty(configKey); return Objects.isNull(config) ? Optional.empty() : Optional.of(config); }
public void get(String configKey, Consumer<String> consumer){ Optional<String> config = get(configKey); if (!config.isPresent()){ log.warn( "application config, get config by key fail, key: {}" , configKey); } config.ifPresent(consumer); }
@Override public void setEnvironment( @NonNull Environment environment) { this .environment = environment; } }
public enum ConfigByEnvironmentKey {
SERVER_PORT( "server.port" , "server port" );
private String key;
private String description;
ConfigByEnvironmentKey(String key, String description) { this .key = key; this .description = description; }
public String getKey() { return key; }
public String getDescription() { return description; } } |
6.测试代码
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
@DisplayName ( "multipart get config" ) @SpringBootTest public class MultipartGetConfigTest {
private static final Logger log = LoggerFactory.getLogger(MultipartGetConfigTest. class );
@Autowired private ConfigByEnvironment configByEnvironment;
@Test public void getByEnvironment(){ configByEnvironment.get(ConfigByEnvironmentKey.SERVER_PORT.getKey()).ifPresent(value -> log.info( "get by environment, value: {}" , value)); }
} |
7.测试结果
org.spring.demo.MultipartGetConfigTest : get by environment, value: 7100
总结
| 通过 @Value 动态获取单个配置 | 使用简单,且使用关联的链路较短 |
1. 配置名不能被有效枚举到 2. 每一个配置的使用都需重新定义,使用较为麻烦 3. 项目强依赖配置的定义,配置不存在则会导致项目无法启动 |
1. 项目强依赖该配置的加载,想要从源头避免因配置缺失导致的未知问题 2. 只想使用少数几个配置 |
| 通过 @ConfigurationProperties + 前缀方式批量获取 |
1. 使用配置只需确定 key 的前缀即能使用,有利于批量获取场景的使用 2. 因采用前缀匹配,所以在使用新的相同前缀 key 的配置时无需改动代码 |
1. 使用复杂,需定义配置类或者手动创建 bean 后引入使用 2. 增加新的前缀相同 key 时可能会引入不稳定因素 |
1. 需要同时使用多前缀相同 key 的配置 2. 期望增加新配置但不修改代码的 properties 注入 |
| 通过 Environment 动态获取单个配置 |
1. 获取的配置的 key 可不提前定义,程序灵活性高 2. 配置 key 可使用枚举统一放置与管理 |
1. 使用较复杂,需继承 Environment 接口形成工具类进行获取 2. 获取 key 对应的枚举与 key 定义分离,value 获取链路较长 |
1. 只需使用少量的配置 2. 获取配置的 key 无提前定义,需要根据对配置的有无进行灵活使用 |
以上就是详解Spring获取配置的三种方式的详细内容,更多关于Spring 获取配置的资料请关注其它相关文章!
原文链接:https://segmentfault测试数据/a/1190000041510290
查看更多关于详解Spring获取配置的三种方式的详细内容...