Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Including profiles with spring.profiles.include seems to override instead of include

Tags:

I'm trying to partition configuration properties for several Spring Boot applications. I'm using Spring Boot 1.1.6, and our configuration properties are expressed in YAML in the usual application.yml style. I've created various profiles for common base parameters, common DB parameters, etc. I was trying to use the include feature mentioned in the Spring Boot reference docs, but it seems to work as an override and not an include. I.e. exactly the opposite of what I want. Given the following content in application.yml, I would have expected the property name to have the value bar when the bar profile is active, but instead it gets set to foo (from the included profile). I thought the notion of including meant that it was loaded first, and any identically named properties set in the new profile would override those from the included profile. Kind of like if a subclass is shadowing a field from the superclass, any instance of the subclass would reflect the shadowed value. Here's the file:

spring:
  profiles: foo
name: foo

--- # New YAML doc starts here

spring:
  profiles: 
    include: foo
  profiles: bar
name: bar

If I run this in a test case with the "bar" profile explicitly activated, the name property will still be foo:

SpringApplicationBuilder builder = new SpringApplicationBuilder(Application.class);
SpringApplication app = builder.application();
builder.profiles("bar");
ConfigurableApplicationContext ctxt = app.run();
String name = ctxt.getEnvironment().getProperty("name"); // Is always "foo" much to my surprise

However, if I comment out the include:

spring: 
profiles: bar
#  profiles: 
#    include: foo

and activate the two profiles explicitly in my code:

builder.profiles("foo", "bar");

Then it works as I would expect, and the name property is set to bar. The main reason I would rather handle the includes in the YAML files is that it's less impact on my actual code, and I can manage all profile inclusion in one place. With the other approach, I'd have to search for profile strings and possible @Profile annotations in my entire project if I were to ever rename the profiles. That's definitely more error prone. I think a more flexible solution would be to explicitly be able to express whether or not the included profile overrides the sub profile values or not. Maybe something like:

spring:
  profiles: bar
  profiles:
    include: foo
      override: false

Maybe I'm just missing something here. Is there a better way of doing this? Thanks.

like image 658
user2337270 Avatar asked Sep 23 '14 02:09

user2337270


People also ask

Can we activate two profiles in spring boot?

Profiles are a core feature of the framework — allowing us to map our beans to different profiles — for example, dev, test, and prod. We can then activate different profiles in different environments to bootstrap only the beans we need.

How many profile can be defined for a spring application?

In the application. properties we have set the local profile to be active. With the SpringApplicationBuilder's profiles method we add two additional profiles.

Are Spring profiles deprecated?

profiles. active cannot be used in a specific environment, i.e. application-<profile>. yaml , nor can it be used in multiple documents separated by --- . In a nutshell, you can no longer use spring.


Video Answer


1 Answers

Try the following for foo to include but override bar, seems to be working for my solution

spring:
    profiles:
        include: bar
        active: foo,bar

edit: please mind, that it's a "hack", not officially supported and it's for 2016 version

like image 111
dpedro Avatar answered Sep 29 '22 09:09

dpedro