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