Reputation: 13882
I have a base YML config for my app, in the class path that looks like this:
hello-world:
values:
bar:
name: bar-name
description: bar-description
foo:
name: foo-name
description: foo-description
hello-world contains a map from string to POJO called values. I want to override the settings in hello-world, in particular I want to delete an entry. So on the local directory where I run the app I have this application.yml:
hello-world:
values:
bar:
name: bar-name
description: bar-description
source: from-the-local-dir
But this doesn't work, because when my local config overrides the existing one, the maps are merged into one and the original entry "foo" is kept. Is there a way to explicitly delete entries from a config map in spring yml?
PS: I can see that the local file get picked up, by modifying the the "bar" entry in the local file. Here's the full code, I've added a "source" config to tell which file was loaded last:
@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();
}
}
}
Upvotes: 3
Views: 2390
Reputation: 2211
Spring boot by default takes file from src/main/resource/application.yml You can declare config/application.yml and those config will override application.yml in src/main/resources
You can just try src/main/resources/application.yml:
hello-world:
bar:
name: bar-name
description: bar-description
foo:
name: foo-name
description: foo-description
And config/application.yml
hello-world:
bar:
name: bar-name
description: bar-description
I think this can help So when you will run your application config/application.yml will override your existing src/main/resources/application.yml
You can completely remove hello-world from config/application.yml But it will throw a runtime exception something like :
Could not resolve placeholder 'hello-world.foo' in value "${hello-world.foo}
To fix it you can apply injecting value like: @Value("${hello-world.foo:}") where after ':' you can define default value
You can leave in config/application.yml empty fields
hello-world:
bar:
name: bar-name
description: bar-description
foo:
name:
description:
By default if you will not specify all values in foo will be empty('') and then you can filter and remove entry with empty values from your map. Also you can look into this class:
Upvotes: 1