Spring Boot按指定前缀后缀读取properties键值对存入HashMap
嘿,我懂你纠结的点了——就是想把properties里那种带固定前缀后缀的键值对,提取出中间的核心部分,转成一个干净的HashMap对吧?我给你两个实用的方案,你可以根据自己的情况选:
方案一:利用@ConfigurationProperties自动绑定(推荐)
其实你已经用到了@ConfigurationProperties,但没完全发挥它的优势。Spring的这个注解本来就擅长处理这种嵌套的属性结构,我们可以直接让它帮我们把属性绑定成Map,不用手动折腾Environment:
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Configuration; import java.util.HashMap; import java.util.Map; @Configuration // 别忘了加这个,让Spring识别为配置类 @ConfigurationProperties(prefix = "pref1.pref2") public class Config { // 这里的变量名"suf"对应properties里的后缀".suf" // Spring会自动把pref1.pref2.abc.suf解析为key=abc,value=1,放进这个Map里 private Map<String, Integer> suf; // 必须要有getter和setter,Spring才能完成绑定 public Map<String, Integer> getSuf() { return suf; } public void setSuf(Map<String, Integer> suf) { this.suf = suf; } // 转成你需要的HashMap返回 public HashMap<String, Integer> getAllProps() { return new HashMap<>(this.suf); } }
这个方案的好处是完全交给Spring处理,不用自己写遍历和字符串截取的逻辑,既简洁又不容易出错。
方案二:手动通过Environment遍历处理
如果你一定要用Environment来手动实现,那可以遍历所有属性键,筛选出符合规则的,再提取核心部分:
import org.springframework.core.env.AbstractEnvironment; import org.springframework.core.env.EnumerablePropertySource; import org.springframework.core.env.Environment; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import java.util.HashMap; import java.util.Arrays; import java.util.stream.Collectors; @Configuration @PropertySource(value = "classpath:sample.properties") public class Config { @Autowired private Environment env; public HashMap<String, Integer> getAllProps() { String prefix = "pref1.pref2."; String suffix = ".suf"; // 遍历所有可枚举的属性源,筛选符合规则的属性 return ((AbstractEnvironment) env).getPropertySources().stream() .filter(propertySource -> propertySource instanceof EnumerablePropertySource) .flatMap(propertySource -> Arrays.stream(((EnumerablePropertySource<?>) propertySource).getPropertyNames())) .filter(propertyName -> propertyName.startsWith(prefix) && propertyName.endsWith(suffix)) .collect(Collectors.toMap( // 提取中间的核心key:去掉前缀和后缀 propertyName -> propertyName.substring(prefix.length(), propertyName.length() - suffix.length()), // 获取对应的值并转成Integer propertyName -> env.getProperty(propertyName, Integer.class), // 如果有重复key,保留后面的值 (value1, value2) -> value2, // 指定返回HashMap类型 HashMap::new )); } }
这个方案需要自己处理属性的遍历和字符串截取,适合需要更自定义逻辑的场景,但要注意不同Environment实现的兼容性问题。
几个注意事项
- 如果你用方案一,记得在pom.xml(Maven)或者build.gradle(Gradle)里引入配置处理器依赖,这样IDE会有属性提示:
<!-- Maven依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency>
- 原来的代码里
@ConfiguraionProperties是拼写错误,正确的是@ConfigurationProperties,别写错了! - 测试的时候,直接在需要的地方注入
Config类,调用getAllProps()就能得到你想要的{"abc":1, "def":2}啦。
内容的提问来源于stack exchange,提问作者Anusha
相关产品推荐
相关产品推荐

