共计 4469 个字符,预计需要花费 12 分钟才能阅读完成。
前言
最近在写框架时遇到须要依据特定配置(可能不存在)加载 bean 的需要,所以就学习了下 Spring 中如何获取配置的几种形式。
Spring 中获取配置的三种形式
- 通过 @Value 形式动静获取单个配置
- 通过 @ConfigurationProperties + 前缀形式批量获取配置
- 通过 Environment 动静获取单个配置
通过 @Value 动静获取单个配置
-
作用
- 可润饰到任一变量获取,应用较灵便
-
长处
- 应用简略,且应用关联的链路较短
-
毛病
- 配置名不能被无效枚举到
- 每一个配置的应用都需从新定义,应用较为麻烦
- 我的项目强依赖配置的定义,配置不存在则会导致我的项目无奈启动
-
应用场景
- 我的项目强依赖该配置的加载,想要从源头防止因配置缺失导致的未知问题
- 只想应用少数几个配置
-
代码示例
@Configuration public class ConfigByValueAnnotation {@Value("${server.port}") private String serverPort; public String getServerPort() {return serverPort;} }
- 测试代码
@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());
}
}
- 测试后果
org.spring.demo.MultipartGetConfigTest : get by @Value, value: 7100
通过 @ConfigurationProperties + 前缀形式批量获取
-
作用
- 用于配置类的润饰或批量配置的获取
-
长处
- 应用配置只需确定 key 的前缀即能应用,有利于批量获取场景的应用
- 因采纳前缀匹配,所以在应用新的雷同前缀 key 的配置时无需改变代码
-
毛病
- 应用简单,需定义配置类或者手动创立 bean 后引入应用
- 减少新的前缀雷同 key 时可能会引入不稳固因素
-
应用场景
- 须要同时应用多前缀雷同 key 的配置
- 冀望减少新配置但不批改代码的 properties 注入
-
代码示例
@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; } }
@Configuration public class ConfigByConfigurationPropertiesV2 {@Bean("configByValueAnnotationV2") @ConfigurationProperties(prefix = "server2") public Properties properties(){return new Properties(); } }
- 测试代码
@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"));
}
}
- 测试后果
org.spring.demo.MultipartGetConfigTest : get by @ConfigurationProperties, value: 7100
org.spring.demo.MultipartGetConfigTest : get by @ConfigurationProperties and manual create bean, value: 7100
通过 Environment 动静获取单个配置
-
作用
- 用于动静在程序代码中获取配置,而配置 key 不需提前定义
-
长处
- 获取的配置的 key 可不提前定义,程序灵活性高
- 配置 key 可应用枚举对立搁置与治理
-
毛病
- 应用较简单,需继承 Environment 接口造成工具类进行获取
- 获取 key 对应的枚举与 key 定义拆散,value 获取链路较长
-
应用场景
- 只需应用大量的配置
- 获取配置的 key 无提前定义,须要依据对配置的有无进行灵便应用
-
代码示例
@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;} }
- 测试代码
@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));
}
}
- 测试后果
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 无提前定义,须要依据对配置的有无进行灵便应用 |
本代码示例已搁置于 github,测试代码地位,有须要的可自取。
本文首发于 cartoon 的博客
正文完