Springboot 无法将属性文件映射到变量

Posted

技术标签:

【中文标题】Springboot 无法将属性文件映射到变量【英文标题】:Springboot failed to map properties file to variable 【发布时间】:2019-05-31 17:46:08 【问题描述】:

我想在 springboot 中用 Map<String, List<String>> 在 yaml 文件之间映射值

country.yml文件:

entries:
  map:
     MY:
      - en
      - zh

SampleConfig文件:

@Configuration
@EnableConfigurationProperties
@ConfigurationProperties("entries")
public class SampleConfig 

    private Map<String, List<String>> map = new HashMap<>();

    @Bean
    public void bean1()
        System.err.println("map has size: "+map.size());
    

但是map.size()总是0,不知道我做错了什么。

【问题讨论】:

我认为你需要 getter/setter 才能工作.. 为什么这个country.yml 不是application.yml 【参考方案1】:

有两个问题

1) 默认情况下,spring 会在默认位置寻找 application.ymlapplication.properties

要解决上述问题,您可以使用application.yml 代替country.yml

2) 您可以使用@PropertySource 加载任何外部属性文件,但此注解不支持yml

24.7.4 YAML Shortcomings 你不能将@PropertySourceyml 文件一起使用

无法使用@PropertySource 注解加载 YAML 文件。因此,如果您需要以这种方式加载值,则需要使用属性文件。

How to read yml file using Spring @PropertySource

【讨论】:

我尝试了 @PropertySource 以及其他人建议的 setter 和 getter,它仍然无法正常工作 @PropertySource 明确还不支持 YAML。 更新了我的答案,收集所有信息需要时间@hades【参考方案2】:

这将起作用并打印出CountryData : MY=[en, zh]

但一定要阅读 Deadpool 的答案。

hack 在这里用 'country' 覆盖默认配置名称 'application'

在示例中,我通过系统属性设置它来完成它,但通过启动您的应用程序 java -jar mycountryapp.jar --spring.config.name=country 应该可以完美运行

@SpringBootApplication
public class Application 

    static 
      System.setProperty("spring.config.name", "country");
    

    public static void main(String[] args) 
        SpringApplication.run(Application.class, args);
    



@Service
class CountryService 
  private final CountryData countryData;
    public CountryService(CountryData countryData) 
        this.countryData = countryData;
    

    @EventListener(ApplicationReadyEvent.class)
    public void showCountryDataOnStartup() 
      System.err.println("CountryData : " + countryData.getMap());
    



@Configuration
@ConfigurationProperties(prefix = "entries")
class CountryData 

    Map<String, List<String>> map;

    public Map<String, List<String>> getMap() 
        return map;
    

    public void setMap(Map<String, List<String>> map) 
        this.map = map;
    


【讨论】:

谢谢!我发现了另一种使用 PropertySourceFactor 从 yaml 文件中读取的方法,如此链接 mdeinum.github.io/2018-07-04-PropertySource-with-yaml-files 中所建议的那样【参考方案3】:

假设您的应用程序正在从country.yml 中选择配置(我也会检查) - 您需要 getter 和 setter 才能使其工作。只需添加:

@Configuration
@EnableConfigurationProperties
@ConfigurationProperties("entries")
public class SampleConfig 

    private Map<String, List<String>> map = new HashMap<>();

    public Map<String, List<String>> getMap()
        return map;
    
    public void setMap(Map<String, List<String>> map)
        this.map=map;
    


【讨论】:

其实我也加了@PropertySource("classpath:country.yml"),但是地图大小还是0

以上是关于Springboot 无法将属性文件映射到变量的主要内容,如果未能解决你的问题,请参考以下文章

SpringBoot 如何将属性配置映射到实体类中?

(三)SpringBoot 配置文件自动映射到属性和实体类

springboot配置文件注解

springboot配置文件自动映射

SpringBoot2.x 集成 Dozer

log4j2 将 xml 映射到属性文件