In the current reference documentation exists the Default Profile section. It has the following content
Starting with a code:
@Configuration
@Profile("default")
public class DefaultDataConfig {
@Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.HSQL)
.addScript("classpath:com/bank/config/sql/schema.sql")
.build();
}
}
and the following content/explanation:
If no profile is active, the
dataSource
is created. You can see this as a way to provide a default definition for one or more beans. If any profile is enabled, the default profile does not apply.You can change the name of the default profile by using
setDefaultProfiles()
on theEnvironment
or, declaratively, by using thespring.profiles.default
property.
Therefore: Why from the beginning was not used directly spring.profiles.active
? - it especially taking in consideration that is known that spring.profiles.active
has more precedence and overrides by complete spring.profiles.default
as indicated in bold above.
As summary:
- Why does
spring.profiles.default
exist if the same approach can be accomplished throughspring.profiles.active
?
Is not clear when is mandatory use the former over the latter - and taking the special consideration about the behavior of overriding if the latter is declared.
Just in case, the @Profile javadoc does not contain some indication about this
I create a post on SO at:
But I think the explanation from the source (here) should be expanded. Thanks for your understanding
Comment From: quaff
It's not clear what will happen if both spring.profiles.active
and spring.profiles.default
are provided, I suspect that spring.profiles.default
is ignored if spring.profiles.active
present.
And what's the differences between @Profile("default")
and absence of @Profile
?
Comment From: snicoll
I don't understand the problem to be honest.
spring.profile.default
defines the name of the default profile(s). That doc states as much:
The name of the default profile is default. You can change the name of the default profile by using setDefaultProfiles() on the Environment or, declaratively, by using the spring.profiles.default property.
So if you set it, you just change the name of the default profile. This doesn't do anything else as described above.
if both spring.profiles.active and spring.profiles.default are provided, I suspect that spring.profiles.default is ignored if spring.profiles.active present.
If you customize the name of the default profile and the you active a profile explicitly, those two things are unrelated. As already stated in the doc, activating a profile means that the default profile fallback does not apply.
And what's the differences between @Profile("default") and absence of @Profile?
That's also unrelated. If you don't have a profile at all, beans are always created. If you have a profile that matches the name of the default profile, it's considered only if no profile is active.
I've polished the section a bit with an explicit link to what it means to activate a profile. If you want to refine, feel free to submit a PR and we can continue the conversation.
Comment From: quaff
It seems that spring.profiles.default
can do everything we need, why there is another spring.profiles.active
?
Comment From: snicoll
Default only set a name to use as a fallback. It’s a mechanism to allow you to enable a profile if no other profile is active. Active predates support for default profile. These are not the same as, as soon as you want certain profiles to he enabled, the default won’t be.
I am sorry but I don’t know where the confusion comes from.
Comment From: quaff
For example, if we defined profile foobar
, then there are two profiles : foobar
and implicit default
, if we want to activate foobar
, we could set spring.profiles.default=foobar
, no need for spring.profiles.active=foobar
, that means spring.profiles.active
is not necessary.
Comment From: bclozel
I don't think this discussion is going anywhere.
Making the case that spring.profiles.active
is useless in some cases and that spring.profiles.default
is enough does not mean that it's not useful. You've just shown that sometimes, technically, it's not needed. We could also make the opposite argument: we could enforce that Spring Framework does not let you change the default profile (always set as "default") and you should only use spring.profiles.active
.
Let's say a company ships a product "myproduct" with customizations for "customerA" and "customerB" that are enabled by Spring profiles. Beans for the vanilla product should be named "default" if we want them to be contributed to the app, unless a "customerA" or "customerB" profile is chosen by the user. It would be nice to have those named "myproduct" as "default" is really generic. If we remove this possibility, developers would rightfully complain that:
- they can't change the name of the default profile to "myproduct" and have to use "default"
- they don't like the fact that they would need to set "myproduct" as active profile by default as it's not a good getting started experience. It should only be required if you choose a particular customer.
- this was working since #12852 and taking it away seems unfair given this has introduced zero bug nor maintenance issue
Comment From: quaff
I'm not saying current design is problematic, I'm saying it confuse people like me.
I suggest the document should be revised to state that both spring.profiles.active
and spring.profiles.default
could activate profiles and the former is recommended, and share a real use case of spring.profiles.default
.
Comment From: rossapi
Hope below analysis would help ( even though it's closed now ) if you consider a real prod-ready case , for example in docker env. say you have 3 env, dev, qa, sat, prod and by default dev should be used ( which also can be changed from arguments by external value ) 1. you may need to pass qa to DOCKER_BUILD_ENV for qa testing build 2. you may need to pass sat to DOCKER_BUILD_ENV or sat build 3. you may need to pass prod to DOCKER_BUILD_ENV or prod build 4. you may not need to pass anything to this var in the local docker build or anywhere not applied in the entrypoint var or env var dev profile will be the fallback moreover SRE/DevOps may pass a different value into a more complex env for this DOCKER_DEFAULT_ENV e.g you docker file may look like this example ENTRYPOINT ["java", "-Dspring.profiles.active=${DOCKER_BUILD_ENV}", "-Dspring.profiles.default=${DOCKER_DEFAULT_ENV}", "-jar", "/testapp.jar"] in this case. SRE gains full control of potential changes of default profile or build profile precisely programmatically , if only using one of active or default. say you only get to set DOCKER_DEFAULT_ENV but spring.profiles.active could be in system level variables ( jvm var can also be the case ).
In short. applying precise spring.profiles.active and spring.profiles.default let 'external team' to external control precisely