- 
                Notifications
    You must be signed in to change notification settings 
- Fork 41.6k
Description
Greetings Spring Boot.  I ran into an unexpected results with the following setup with config loading.  Let's consider we have the following application.yml file.
test:
  environment: test
---
spring:
  config:
    activate:
      on-profile: profileA
test:
  environment: prod
---
spring:
  config:
    activate:
      on-profile: profileB
    import:
      - application/${test.environment}.yml
otherProp: ${test.environment}  And we have application/prod.yml with the following contents:
myTestProp: testProp/prod
And application/test.yml with the following contents:
myTestProp: testProp/test
And finally we have the following test that will activate profileB and assert on expected results.
@ActiveProfiles(profiles = "profileB")
@SpringBootTest
public class ProfileBPropsTest {
    @Autowired
    private Environment env;
    @Test
    public void Test() {
        assertEquals("test", env.getProperty("test.environment", String.class));
        assertEquals("test", env.getProperty("otherProp", String.class));
        assertEquals("testProp/test", env.getProperty("myTestProp", String.class));
    }
    @Configuration
    class TestConfig {}And we have the following test to activate both profiles profileA and profileB and assert on expected results.
@ActiveProfiles(profiles = {"profileA", "profileB"})
@SpringBootTest
public class ProfileABPropsTest {
    @Autowired
    private Environment env;
    @Test
    public void Test() {
        assertEquals("prod", env.getProperty("test.environment", String.class));
        assertEquals("prod", env.getProperty("otherProp", String.class));
        assertEquals("testProp/prod", env.getProperty("myTestProp", String.class));
    }
    @Configuration
    class TestConfig {}
}What I've observed is ProfileABPropsTest passes expectedly.  The file-order profile activation picks up the override for test.environment in profileA which is then used in profileB to import prod.yml as a property source.
However what fails is ProfileBPropsTest.   Only profileB is active, so we assume the default value of test.environment=test will cause test.yml to be imported as a property source.  Instead what we find is the value of myTestProp=testProp/prod which would only happen if prod.yml was loaded.  But as we can see by the test, test.environment=test, so how is it that we get this property in this scenario unless the expression ${test.environment} is pulling in an incorrect value that should technically only happen if profileA is activated.
I cannot explain this from reading the Spring documentation. For context, I am seeing this in spring boot 2.5.x.