Spring Boot读取没有前缀的属性到一个映射中

7

我需要将application.properties文件中的所有属性读入到一个映射中

在下方的代码中,属性test有相应的值,但是映射为空。如何在不添加前缀的情况下填充“map”以包含application.properties文件中的值。

这是我的application.properties文件

AAPL=25
GDDY=65
test=22

我正在这样使用@ConfigurationProperties
@Configuration
@ConfigurationProperties("")
@PropertySource("classpath:application.properties")
public class InitialConfiguration {
    private HashMap<String, BigInteger> map = new HashMap<>();
    private String test;

    public HashMap<String, BigInteger> getMap() {
        return map;
    }

    public void setMap(HashMap<String, BigInteger> map) {
        this.map = map;
    }

    public String getTest() {
        return test;
    }

    public void setTest(String test) {
        this.test = test;
    }
}
5个回答

4
这可以通过使用PropertiesLoaderUtils@PostConstruct实现。
请参考下面的示例:
@Configuration
public class HelloConfiguration {
    private Map<String, String> valueMap = new HashMap<>();
    @PostConstruct
    public void doInit() throws IOException {
        Properties properties = PropertiesLoaderUtils.loadAllProperties("application.properties");
        properties.keySet().forEach(key -> {
            valueMap.put((String) key, properties.getProperty((String) key));
        });
        System.err.println("valueMap -> "+valueMap);
    }
    public Map<String, String> getValueMap() {
        return valueMap;
    }
    public void setValueMap(Map<String, String> valueMap) {
        this.valueMap = valueMap;
    }
}

4
据我所知,您无法使用@ConfigurationProperties达到此目的,因为它们需要前缀才能在Bean中加载这些属性。但是,如果您的目标是以编程方式获取“属性X”的“值Y”,则始终可以注入Environment并使用getProperty()方法查找某个属性,例如:
@Configuration
public class InitialConfiguration {
    @Autowired
    private Environment environment;

    @PostConstruct
    public void test() {
        Integer aapl = environment.getProperty("AAPL", Integer.class); // 25
        Integer gddy = environment.getProperty("GDDY", Integer.class); // 65
        Integer test = environment.getProperty("test", Integer.class); // 22
    }
}

谢谢,我尝试过这个方法,但不想直接使用环境变量,不过这是最简单的解决方案。 - Jorge Miralles
这应该是被选中的答案。通过环境加载是最健壮的方式。 - Amit Goldstein
PropertiesLoaderUtils将在构建时加载属性。如果我们稍后更改属性并重新运行JAR,则PropertiesLoaderUtils不会反映新的更改。在这方面,Environment是最好的方式。 - skaveesh

2
在Spring Boot中,如果您需要从application.properties获取单个值,只需使用给定名称的@Value注释即可。
因此,要获取AAPL值,只需添加一个类级属性,如下所示:
@Value("${AAPL}")
private String aapl;

如果您需要将完整的属性文件加载为映射,我使用ResourceLoader将完整文件加载为流,然后按以下方式解析它

@Autowired
public loadResources(ResourceLoader resourceLoader) throws Exception {      
      Resource resource = resourceLoader.getResource("classpath:myProperties.properties"));
      BufferedReader br = new BufferedReader(new InputStreamReader(resource.getInputStream()));
      String line;
      int pos = 0;
      Map<String, String> map = new HashMap<>();
      while ((line = br.readLine()) != null) {
           pos = line.indexOf("=");
           map.put(line.substring(0, pos), line.substring( pos + 1));
      }
}

1

实际上,您可以使用没有前缀的@ConfigurationProperties来获取Spring应用程序知道的所有属性,即应用程序、系统和环境属性等。

以下示例创建一个完全填充的映射作为Spring bean。然后在需要它的地方连接/注入这个bean。

@Configuration
class YetAnotherConfiguration {

    @ConfigurationProperties /* or @ConfigurationProperties("") */
    @Bean
    Map<String, String> allProperties() {
        return new LinkedHashMap<>();
    }

}

@Autowire
void test(Map<String, String> allProperties) {
    System.out.println(allProperties.get("AAPL")); // 25
    ...
}

Spring Boot的新版本现在要求@ConfigurationProperties(prefix = "non-empty")注释必须有一个强制性的prefix参数。 - MarkHu
实际上,IntelliJ 抱怨“必须指定前缀”或“前缀不能为空”,但在 ConfigurationProperties 的文档中没有提到任何限制。看起来这是一个检查错误。- IDEA-219436 - bjmi

0
@PropertySource("classpath:config.properties")
public class GlobalConfig {

  public static String AAPL;
  @Value("${AAPL}")
  private void setDatabaseUrl(String value) {
    AAPL = value;
  }
}

你需要使用@Value从application.properties文件中获取值


这并没有回答OP的问题,他想要动态获取所有属性的列表。 - MarkHu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接