2

Is there a defined order when multiple profiles are used for a property resolution.

I have yaml configuration file:

name: none
---
spring:
  profiles: prod
name: prodName
---
spring:
  profiles: dev
name: devName

When application runs with no (default) profile, none is printed. For dev/prod profiles devName/prodName is printed (so far so good).

When I tried to define profile as dev,prod prodName is printed,when I specify prod,dev devName is printed.

Is this something I can rely on? I mean is it specified in Spring? I didn't find it here.

full version (for replication)

application.yml

name: none
---
spring:
  profiles: dev
name: devName
---
spring:
  profiles: prod
name: prodName

Configuration.java

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

@Component
@ConfigurationProperties
public class Configuration {

    String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

SpringBootConsoleApplication.java

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import java.util.List;

@SpringBootApplication
public class SpringBootConsoleApplication implements CommandLineRunner {

    private static Logger LOG = LoggerFactory.getLogger(SpringBootConsoleApplication.class);

    @Autowired
    Configuration conf;

    public static void main(String[] args) {
        SpringApplication.run(SpringBootConsoleApplication.class, args);
    }

    @Override
    public void run(String... args) {
        LOG.info("name: {}", conf.name);
    }

}

edit:

GitHub repository

sample output:

c:\betlista\SpringPropertyResolutionMultipleProfiles>java -jar target\spring-boot-console-app-1.0.jar
...: name: none, label: labelValue

c:\betlista\SpringPropertyResolutionMultipleProfiles>java -jar -Dspring.profiles.active=dev target\spring-boot-console-app-1.0.jar

...: name: devName, label: labelValue

c:\betlista\SpringPropertyResolutionMultipleProfiles>java -jar -Dspring.profiles.active=dev,prod target\spring-boot-console-app-1.0.jar

...: name: prodName, label: labelValue

c:\betlista\SpringPropertyResolutionMultipleProfiles>java -jar -Dspring.profiles.active=prod,dev target\spring-boot-console-app-1.0.jar

...: name: devName, label: labelValue

edit 2:

Topics

There was a question which I'd refer to as topics - Multiple properties file for a single spring profile

While one can use @PropertySource with property files, it cannot be used with YAML files. The only solution I know at the moment is to used e.g. -Dspring.config.additional-location=classpath:topic1.yml

edit 3:

The "duplicate" question has same questions as I have here, but without an answer. That question was about beans, not really a properties. Accepted answer says "spring.profiles.active system property doesn't matter.", which I shown as incorrect (within context of properties). Please vote for reopen if you agree.

Betlista
  • 10,327
  • 13
  • 69
  • 110
  • 1
    It will override by last profile given in .yml file. if you have defined dev and then prod. Then eventually prod will be overriden. – GnanaJeyam Feb 21 '20 at 07:41
  • No, this is not how it works for me... It depends on what you specify as active profile... – Betlista Feb 21 '20 at 08:12
  • This question was closed without proper answer, please vote for reopen as creation of new one (copy) makes no sense to me... – Betlista Dec 16 '20 at 09:41
  • The part in bold in the answer is all that you need: "the last bean definition wins". When you use "prod,dev" the "dev" keys are going to be loaded *after* the "prod" keys, hence what you've noticed yourself. – Stephane Nicoll Dec 16 '20 at 10:29
  • @StephaneNicoll I do not see the connection between bean and properties loading, the answer at the beginning says also "The order of the profiles in the spring.profiles.active system property doesn't matter.", which is clearly not correct. Other answer by Patrick Cornelissen says, that order is not defined and is important in profile based configuration. I'd expect this is written in documentation somewhere, which IMHO is not or I didn't find it... – Betlista Dec 16 '20 at 11:14
  • 1
    Yeah, I can see how the original question is not the same as yours (except that the outcome is the same). I'll add an answer here shortly. – Stephane Nicoll Dec 16 '20 at 16:39

1 Answers1

2

Is this something I can rely on?

Yes, the last-win strategy is consistent and is documented in the reference guide:

If several profiles are specified, a last-wins strategy applies. For example, if profiles prod,live are specified by the spring.profiles.active property, values in application-prod.properties can be overridden by those in application-live.properties.

(Unrelated, but about the link to the doc you've shared. I don't know if that's an accident but that's the documentation for Spring Boot 1.2.x which was released over 6 years ago).

Stephane Nicoll
  • 31,977
  • 9
  • 97
  • 89
  • Thanks, exactly what I was looking for. Maybe I was working with some Spring Boot 1.2 application that time... – Betlista Dec 16 '20 at 17:14