0

For Spring about Profiles, the following is legal

ConfigurableApplicationContext ctx =
        new AnnotationConfigApplicationContext("com.manuel.jordan.config");
ctx.getEnvironment().setActiveProfiles("jdbc", "mysql");
...

But the following approach is valid too.

//B1
System.setProperty("spring.profiles.active", "jdbc", "mysql");
ConfigurableApplicationContext ctx =
        new AnnotationConfigApplicationContext("com.manuel.jordan.config");
...

Both approaches are applied in peace and the app works as expected ... but

Question

  • When is mandatory define the profiles through Environment over System.setProperty and viceversa?

Extra Question

  • Why was created the approach to define a profile (default or active) through Environment if can be accomplished through System.setProperty too? Being the later plain Java
Manuel Jordan
  • 15,253
  • 21
  • 95
  • 158

1 Answers1

3
ConfigurableApplicationContext ctx =
        new AnnotationConfigApplicationContext("com.manuel.jordan.config");
ctx.getEnvironment().setActiveProfiles("jdbc", "mysql");
...

Here you have to watch out! Your active profiles are jdbc and mysql as expected. But NO beans were created based on those profiles!

In the second approach with System.setProperty("spring.profiles.active", "jdbc, mysql"); (before creating the ApplicationContext) beans will be created based on those profiles!

Demo

@Configuration
public class MyConfiguration {

    @Bean(name = "jdbc")
    @Profile("jdbc")
    public MyProfileClass jdbc(){
        return new MyProfileClass("jdbc");
    }

    @Bean(name = "mysql")
    @Profile("mysql")
    public MyProfileClass mysql(){
        return new MyProfileClass("mysql");
    }

    @Bean(name = "notJdbc")
    @Profile("!jdbc")
    public MyProfileClass notJdbc(){
        return new MyProfileClass("not jdbc");
    }

    @Bean(name = "notMysql")
    @Profile("!mysql")
    public MyProfileClass notMysql(){
        return new MyProfileClass("not mysql");
    }
}

public class MyProfileClass {

    private final String name;

    public MyProfileClass(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return name;
    }
}


public class DemoApplication {

    public static void main(String[] args) {
//        System.setProperty("spring.profiles.active", "jdbc,mysql");
        ConfigurableApplicationContext ctx =
                new AnnotationConfigApplicationContext("com.manuel.jordan.config");
        ctx.getEnvironment().setActiveProfiles("jdbc", "mysql"); // to late beans based on profile already created

        System.out.println(Arrays.asList(ctx.getEnvironment().getActiveProfiles()));

        for (String beanName:ctx.getBeanDefinitionNames()) {
            System.out.println(ctx.getBean(beanName));
        }
    }
}

There are more options to activate different profiles: Baeldung :: Spring Profiles


UPDATE

When you want to set the active profiles programmatically use, you need to refresh the context.

like:

AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();

ctx.getEnvironment().setActiveProfiles("jdbc", "mysql");
ctx.scan("com.manuel.jordan.config");
ctx.refresh();

Dirk Deyne
  • 6,048
  • 1
  • 15
  • 32
  • 1
    Thanks for your reply - I am doing my experiment by my side for confirmations and other things - just being curious if `ctx.getEnvironment().setActiveProfiles("jdbc", "mysql");` does **not** work, Therefore What is its purpose? – Manuel Jordan Apr 25 '23 at 19:20
  • 1
    `ctx.getEnvironment().setActiveProfiles("jdbc", "mysql")` only works if you refresh the context; @see update – Dirk Deyne Apr 25 '23 at 21:02
  • 1
    About the `refresh` method - pls, read carefully the following https://stackoverflow.com/questions/75442297/spring-framework-why-the-active-profiles-declared-programmatically-are-working - specially starting from _Even more, like a simple plus, if is executed as:_ - it seems the approach to create the App is tricky ... in your case you use the non-arguments constructor and my case yes (in the other post) now is clear for me when use the `register` and `scan` methods and later the `refresh` method – Manuel Jordan Apr 25 '23 at 21:21