We are currently having one application.properties
and one application-staging.properties
, which is loaded based on the active Spring profile.
However, it's very bloated and we like to split it into multiple properties files based on the context.
For example:
teams.properties
and
teams-staging.properties
We load it using the class below
@Getter
@Configuration
@PropertySource("classpath:teams.properties")
public class TeamsProperties {
@Value("${teams.some-team-a}")
private String someTeamA;
@Value("${teams.some-team-b}")
private String someTeamB;
}
But it won't respect the profile and the teams-staging.properties
is ignored.
What would be needed to "clone" the default application.properties behaviour for custom properties files?
CodePudding user response:
@PropertySource accept an array as value. You can do this :
@Getter
@Configuration
@PropertySource({"classpath:teams.properties", "classpath:teams-${spring.profiles.active}.properties"})
public class TeamsProperties {
@Value("${teams.some-team-a}")
private String someTeamA;
@Value("${teams.some-team-b}")
private String someTeamB;
}
Then run the application with the active profile :
-Dspring.profiles.active=staging
The disadvantage of this solution is that you always have to pass only one active profile. It will not work for multiple profiles : -Dspring.profiles.active=foo,bar
CodePudding user response:
I've decided to do it via inheritance as @xerx593 recommended in the comment.
@Getter
public abstract class TeamsProperties {
@Value("${teams.some-team-a}")
private String someTeamA;
@Value("${teams.some-team-b}")
private String someTeamB;
@Configuration
@Profile({"!staging"})
@PropertySource({"classpath:teams.properties"})
public static class TeamsPropertiesDefault extends TeamsProperties {
}
@Configuration
@Profile({"staging"})
@PropertySource({"classpath:teams-staging.properties"})
public static class TeamsPropertiesDynamic extends TeamsProperties {
}
}
The reason is, I'd like to keep teams.properties as the default properties file and only then switch to staging if the profile is staging. I also don't want to have to create one additional .properties file for each profile, like "testing".
So with that way, each profile that is not covered with a specific properties file will always fall back to teams.properties ( but the @Profile annotation of the default must be enhanced of course)
Putting it all together with inner classes keeps it relatively clean and I can live with it.