I'm looking for a way to manipulate @ConfigurationProperties
defined on initialization so that when I @Inject / @Autorwired
the configured object using a @Bean
method it is properly configured.
Scenario:
I have a bunch of properties set in a .yml
file. Because all of these properties match as Strings some of them need special handling to be properly configured to their respective types (some of them are enums). Do I make my properties object a @Component
then inject it into the @Bean
method and modify it? I tried to combine @Bean
and @ConfigurationProperties
annotations but the object is configured AFTER the @Bean
method itself returns, so any manipulation is lost/impossible. What is the best way to do this?
Example:
In my .yml
i have this:
properties:
sports:
"football": ["Team 1", "Team 2", "Team 3"]
"basketball": ["Team 4", "Team 5", "Team 6"]
settings:
"football":
"period1": "45"
"period2": "90"
"players": "11"
"basketball":
"periods": "4"
"players": "5"
And these match with the following objects:
Map<SportsEnum, List<TeamsEnum>
Map<SportsEnum, Map<SportSettingsEnum, String>>
TL;DR:
I want to take an object configured from a .yml/.properties
file and manipulate its injectable representation. Please provide concrete example!
This is definitely supported, my guess is that you're doing something wrong. Let's go step by step.
First, your YAML file is badly formatted, it should look something like this:
properties:
sports:
football:
- Team1
- Team2
- Team3
basketball:
- Team4
- Team5
- Team6
settings:
football:
period1: 45
period2: 90
players: 11
basketball:
periods: 4
players: 5
Then, your configuration properties would look like this:
@ConfigurationProperties(prefix = "properties", locations = "classpath:sports.yml")
public class SportsProperties {
private Map<SportsEnum, List<TeamsEnum>> sports;
private Map<SportsEnum, Map<SportSettingsEnum, String>> settings;
public Map<SportsEnum, List<TeamsEnum>> getSports() {
return sports;
}
public void setSports(Map<SportsEnum, List<TeamsEnum>> sports) {
this.sports = sports;
}
public Map<SportsEnum, Map<SportSettingsEnum, String>> getSettings() {
return settings;
}
public void setSettings(
Map<SportsEnum, Map<SportSettingsEnum, String>> settings) {
this.settings = settings;
}
@PostConstruct
public void customManipulation() {
System.out.println(sports);
System.out.println(settings);
}
}
Next, the properties should be enabled in your configuration:
@SpringBootApplication
@EnableConfigurationProperties(SportsProperties.class)
public class YamlSampleApplication {
public static void main(String[] args) {
SpringApplication.run(YamlSampleApplication.class, args);
}
}
That should be it, really. Here are my enums:
public enum SportsEnum {
football, basketball
}
public enum TeamsEnum {
Team1, Team2, Team3, Team4, Team5, Team6
}
public enum SportSettingsEnum {
periods, period1, period2, players
}
Here's the output I get in the logs:
2016-07-26 17:44:41.226 DEBUG 30015 --- [ main] s.b.e.YamlPropertySourceLoader$Processor : Loading from YAML: class path resource [sports.yml]
2016-07-26 17:44:41.282 DEBUG 30015 --- [ main] s.b.e.YamlPropertySourceLoader$Processor : Matched document with default matcher: {properties={sports={football=[Team1, Team2, Team3], basketball=[Team4, Team5, Team6]}, settings={football={period1=45, period2=90, players=11}, basketball={periods=4, players=5}}}}
2016-07-26 17:44:41.282 DEBUG 30015 --- [ main] s.b.e.YamlPropertySourceLoader$Processor : Loaded 1 document from YAML resource: class path resource [sports.yml]
{football=[Team1, Team2, Team3], basketball=[Team4, Team5, Team6]}
{football={period1=45, period2=90, players=11}, basketball={periods=4, players=5}}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With