Spring Boot-YML配置-合并时擦除条目

时间:2018-11-07 12:14:37

标签: java spring spring-boot configuration yaml

在类路径中,我的应用具有基本的YML配置,如下所示:

hello-world:
  values:
    bar:
      name: bar-name
      description: bar-description
    foo:
      name: foo-name
      description: foo-description

hello-world包含从字符串到POJO的映射,称为值。我想覆盖hello-world中的设置,尤其是要删除一个条目。因此,在运行应用程序的本地目录上,我有此应用程序。yml:

hello-world:
  values:
    bar:
      name: bar-name
      description: bar-description

source: from-the-local-dir

但是这不起作用,因为当我的本地配置覆盖现有配置时,地图将合并为一个,并保留原始条目“ foo”。有没有办法在Spring yml中从配置映射中显式删除条目?

PS:通过修改本地文件中的“ bar”条目,我可以看到本地文件被拾取。这是完整的代码,我添加了一个“源”配置来告诉最后一个文件:

@Import(PlayGround.Config.class)
@SpringBootApplication
public class PlayGround {

    @Autowired
    Config config;

    @Value("${source}")
    String source;

    public void start() {
        System.out.println(config);
        System.out.println(source);
    }

    public static void main(String[] args) {
        System.out.println(Arrays.toString(args));
        ConfigurableApplicationContext context = SpringApplication.run(PlayGround.class, args);
        PlayGround playGround = context.getBean(PlayGround.class);
        playGround.start();
    }

    @ConfigurationProperties(prefix = "hello-world")
    public static final class Config {
        Map<String, Information> values = new HashMap<String, Information>();

        public Map<String, Information> getValues() {
            return values;
        }

        public void setValues(Map<String, Information> values) {
            this.values = values;
        }

        @Override
        public String toString() {
            return MoreObjects.toStringHelper(this)
                    .add("values", values)
                    .toString();
        }
    }

    public static final class Information {

        String name;
        String description;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getDescription() {
            return description;
        }

        public void setDescription(String description) {
            this.description = description;
        }

        @Override
        public String toString() {
            return MoreObjects.toStringHelper(this)
                    .add("name", name)
                    .add("description", description)
                    .toString();
        }
    }

}

1 个答案:

答案 0 :(得分:2)

Spring引导默认情况下从src / main / resource / application.yml中获取文件 您可以声明config / application.yml,这些配置将覆盖src / main / resources中的application.yml

您可以尝试src / main / resources / application.yml:

hello-world:
  bar: 
    name: bar-name
    description: bar-description
  foo: 
    name: foo-name
    description: foo-description

和config / application.yml

  hello-world:
      bar: 
        name: bar-name
        description: bar-description

我认为这可以有所帮助 因此,当您运行应用程序时,config / application.yml将覆盖现有的src / main / resources / application.yml

您可以从config / application.yml中完全删除hello-world。 但是它将抛出运行时异常,例如:

Could not resolve placeholder 'hello-world.foo' in value "${hello-world.foo}

要解决此问题,您可以应用注入值,例如: @Value(“ $ {hello-world.foo:}”) 在':'之后的位置,您可以定义默认值

您可以在config / application.yml中保留空白字段

hello-world:
  bar: 
    name: bar-name
    description: bar-description
  foo: 
    name:
    description:

默认情况下,如果您不指定foo中的所有值,则将为empty(''),然后可以从地图中过滤并删除具有空值的条目。 您也可以研究此类:

https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/beans/factory/config/YamlProcessor.ResolutionMethod.html