Spring choose property source by a combination of profiles

Tags: , , , ,



I have multiple environments driven by Spring profiles, such as application-int.yml, application-dev.yml etc with similar content:

  • application-int.yml
    ws:
       endpoint: http://my-soap-int-endpoint.com/
       mock: http://my-soap-int-mock-endpoint.com/
    
  • application-dev.yml
    ws:
      endpoint: http://my-soap-dev-endpoint.com/
      mock: http://my-soap-dev-mock-endpoint.com/
    

My goal is to use the following property based on both the environment name and whether the mock profile is included:

  • ws.endpoint from application-dev.yml for dev profiles
  • ws.endpoint from application-int.yml for int profiles
  • ws.mock from application-dev.yml for dev mock profiles
  • ws.mock from application-int.yml for int mock profiles

I need to parse that value into a single variable url:

@Configuration
public class SoapConfiguration {

    @Value("???")                  // based on 2 properties
    private String wsUrl;
}

I would like to avoid complicated hierarchy of abstract configuration classes only based on @Profile. Moreover, I need to keep to keep both variables (mock and non-mock) in a common propery file.

Is there a nice way that is both readable and maintainable?

Answer

You can set wsUrl in constructor. It’s not so elegant solution but it works. Inject Environment bean to your SoapConfiguration and check is mock profile active.
Code example:

@Configuration
public class SoapConfiguration {
    private final String wsUrl;

    public SoapConfiguration(Environment environment) {
        if (Arrays.asList(environment.getActiveProfiles()).contains("mock")) {
            this.wsUrl = environment.getProperty("ws.mock");
        } else {
            this.wsUrl = environment.getProperty("ws.endpoint");
        }
    }
}


Source: stackoverflow