249

I need to code different logic based on different current Environment profile.

How can you get the currently active and default profiles from Spring?

catch23
  • 17,519
  • 42
  • 144
  • 217
Bobo
  • 8,777
  • 18
  • 66
  • 85
  • 4
    @aweigold: get current active/default Environment profile programatically in spring 3.1. what more details you need? – Bobo Feb 13 '12 at 21:00

8 Answers8

333

You can autowire the Environment

@Autowired
Environment env;

Environment offers:

Ivar
  • 6,138
  • 12
  • 49
  • 61
aweigold
  • 6,532
  • 2
  • 32
  • 46
  • 21
    How can I get such thing in **static** methods in **non-spring-managed** classes? – Aetherus Feb 01 '19 at 01:59
  • 1
    I'd try adding the profile-name as a method parameter and pass it from the calling class. – boutta Feb 08 '21 at 15:15
  • Looks like Spring 5.1 deprecated `acceptsProfiles(String... profiles)` and replaced it with `acceptsProfiles(Profiles profiles)`. – M. Justin Feb 28 '22 at 19:29
140

Extending User1648825's nice simple answer:

@Value("${spring.profiles.active}")
private String activeProfile;

This may throw an IllegalArgumentException if no profiles are set (I get a null value). This may be a Good Thing if you need it to be set; if not use the 'default' syntax for @Value, ie:

@Value("${spring.profiles.active:Unknown}")
private String activeProfile;

...activeProfile now contains 'Unknown' if spring.profiles.active could not be resolved

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
MartinMlima
  • 1,736
  • 1
  • 12
  • 13
  • 2
    Profile names are separated by a comma. Checkout https://www.baeldung.com/spring-profiles#2-using-springactiveprofile – Jason May 12 '20 at 02:24
  • 1
    It doesn't work when making get injected in SpringBootTest. Injecting Environment works – Wood Dec 28 '22 at 11:26
  • see discussion on `@SpringBootTest` and `@ActiveProfiles` and why/how it was changed from Spring Boot 2.3 onwards [here](https://github.com/spring-projects/spring-boot/issues/19788) – hello_earth Apr 01 '23 at 13:45
73

Here is a more complete example.

Autowire Environment

First you will want to autowire the environment bean.

@Autowired
private Environment environment;

Check if Profiles exist in Active Profiles

Then you can use getActiveProfiles() to find out if the profile exists in the list of active profiles. Here is an example that takes the String[] from getActiveProfiles(), gets a stream from that array, then uses matchers to check for multiple profiles(Case-Insensitive) which returns a boolean if they exist.

//Check if Active profiles contains "local" or "test"
if(Arrays.stream(environment.getActiveProfiles()).anyMatch(
   env -> (env.equalsIgnoreCase("test") 
   || env.equalsIgnoreCase("local")) )) 
{
   doSomethingForLocalOrTest();
}
//Check if Active profiles contains "prod"
else if(Arrays.stream(environment.getActiveProfiles()).anyMatch(
   env -> (env.equalsIgnoreCase("prod")) )) 
{
   doSomethingForProd();
}

You can also achieve similar functionality using the annotation @Profile("local") Profiles allow for selective configuration based on a passed-in or environment parameter. Here is more information on this technique: Spring Profiles

anataliocs
  • 10,427
  • 6
  • 56
  • 72
37
@Value("${spring.profiles.active}")
private String activeProfile;

It works and you don't need to implement EnvironmentAware. But I don't know drawbacks of this approach.

user1648825
  • 979
  • 11
  • 19
  • 8
    This line gives this error: `Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'spring.profiles.active' in value "${spring.profiles.active}"` – zygimantus Jan 04 '18 at 09:07
  • Works perfectly for me. Using Spring Boot 1.5.15. – рüффп Aug 30 '18 at 09:05
  • I think if the profile is defined, value will be parsed, otherwise the exception arises. Does not fit all situations. – WesternGun Jan 14 '19 at 15:53
  • 3
    Active profile also could be an array, take attention to that please. Using such way you can get unexpected error on adding additional profiles. – Oleksandr Yefymov Mar 07 '19 at 16:33
  • 2
    The drawback to this approach is that it won't get all of the profiles that Spring might consider when evaluating `@Profile`. Apps can also use the `spring.profiles.include` property, and can set profiles programmatically during initialization using `ConfigurableEnvironment`. `Environment.getActiveProfiles()` will get the full list of profiles set using any of these mechanisms. – Scott Frederick Jul 05 '19 at 18:57
  • I am getting null – Girish Dec 24 '21 at 08:24
20

As already mentioned earlier. You could autowire Environment:

@Autowired
private Environment environment;

only you could do check for the needed environment much easier:

if (environment.acceptsProfiles(Profiles.of("test"))) {
    doStuffForTestEnv();
} else {
    doStuffForOtherProfiles();
}
catch23
  • 17,519
  • 42
  • 144
  • 217
17

If you're not using autowiring, simply implement EnvironmentAware

Arnout Engelen
  • 6,709
  • 1
  • 25
  • 36
9

Seems there is some demand to be able to access this statically.

How can I get such thing in static methods in non-spring-managed classes? – Aetherus

It's a hack, but you can write your own class to expose it. You must be careful to ensure that nothing will call SpringContext.getEnvironment() before all beans have been created, since there is no guarantee when this component will be instantiated.

@Component
public class SpringContext
{
    private static Environment environment;

    public SpringContext(Environment environment) {
        SpringContext.environment = environment;
    }

    public static Environment getEnvironment() {
        if (environment == null) {
            throw new RuntimeException("Environment has not been set yet");
        }
        return environment;
    }
}
Michael
  • 41,989
  • 11
  • 82
  • 128
5

And if you neither want to use @Autowire nor injecting @Value you can simply do (with fallback included):

System.getProperty("spring.profiles.active", "unknown");

This will return any active profile (or fallback to 'unknown').

embuc
  • 465
  • 5
  • 5