This tutorial shows you various ways to read system environment variables in a Spring Boot application.
An operating system usually has some values defined as the system environment variables. If you have a Spring Boot application and you need to read one of the variables, there are several ways to do it. Below are the examples.
Using @Value
Annotation
The simplest way to read an environment variable is by using the @Value
annotation. You can directly write the name in the same way as you refer to an application property. The format is ${env_var_name}
. For example, if there is an environment variable named MYENV
, you can use the below annotation.
@Value("${MYENV}")
private String myEnv;
The code above may throw an exception if the environment variable is not defined.
Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'MYENV' in value "${MYENV}"
If you want to handle it, just add a default value after the name separated by :
symbol.
@Value("${MYENV:foo}")
private String myEnv;
Using Application Property Placeholder
Another way is by using a placeholder in the application property. You can define a property with any name. To make the value refer to an environment variable, you have to write it in ${env_var_name}
format. By default, Spring will automatically resolve the value if it's defined. Below is the example for application.properties
.
com.woolha.my-env=${MYENV}
Below is the example for application.yml
.
com:
woolha:
my-env: ${MYENV}
If it's not defined, you'll get the IllegalArgumentException
as well. The solution is the same, you can add a default value after the name separated by :
symbol.
Handle Gradle Process Resources
If you use Gradle as the build tools and enable processResources
on the application.properties
or application.yml
file, you may need a little workaround since Gradle also uses the same syntax (${var_name}
) for referencing a variable. As a result, it may not be able to resolve the environment variable value by default. The workaround is by adding \
symbol before to escape it so that it's not processed by Gradle.
com.woolha.my-env=\${MYENV}
Using Environment
Spring has an interface called Environment
which represents the environment in which the current application is running. It can be easily autowired in any Spring managed class. The Environment
interface extends the PropertyResolver
interface which defines some methods for getting the value of an environment variable.
There are some methods named getProperty
with different signatures. They can be used to get the value of a property including an application property or a system environment variable. It will return null
if the property is not defined. There are methods that provide a parameter for defining a default value to be returned if the property is not defined. Some of the methods also have a target type parameter which is used to cast the read value to a specified type.
String getProperty(String key);
String getProperty(String key, String defaultValue);
<T> T getProperty(String key, Class<T> targetType);
<T> T getProperty(String key, Class<T> targetType, T defaultValue);
Below are the examples.
@Service
public class MyService {
public MyService(Environment environment) {
this.environment = environment;
}
public void doSomething() {
String a = this.environment.getProperty("MYENV");
String b = this.environment.getProperty("MYENV", "0");
Integer c = this.environment.getProperty("MYENV", Integer.class);
Integer d = this.environment.getProperty("MYENV", Integer.class, 0);
}
}
If you use the methods with the target type parameter, the value must be be able to be converted to the specified type. Otherwise, you'll get a ConversionFailedException
. For example, if the value type is String but the passed type is Integer, below is the thrown exception.
[Request processing failed: org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.lang.Integer] for value [Woolha.com]] with root cause
There are also methods named getRequiredProperty
which do the similar thing, except they will throw IllegalStateException
if the key cannot be resolved.
String getRequiredProperty(String key) throws IllegalStateException;
<T> T getRequiredProperty(String key, Class<T> targetType) throws IllegalStateException;
Below are the examples.
public void doSomething() {
String e = this.environment.getRequiredProperty("MYENV");
Integer f = this.environment.getRequiredProperty("MYENV", Integer.class);
}
Using System.getEnv
Because Spring is a Java framework, you can also use Java's System.getEnv
method to get the value of a specified environment variable programmatically. If the variable is not defined, it will return null
. It can also return a SecurityException
if the application is not allowed to access it.
public static String getenv(String name)
Example:
System.getenv("MYENV")
Summary
There are several ways to read a system environment variable in a Spring Boot application. You can use the @Value
annotation, application property placeholder, or Spring's Environment
object. It's also possible to use Java's System.getEnv
method.
You can also read about:
- How to use
EnvironmentPostProcessor
, in case you need to process the system environment variable.