
Spring Boot : Configuring environment variables
In any spring boot application, at some point or the other you will have to externalise your configurations for obvious benefits.
As the application gets larger you have multiple environments like production, development, test etc each with their own specific configurations.
Spring provides many ways to do handle such scenarios by isolating different configurations and using them according to the environment.
Spring does this using something called as profile.
About which you can read more here:
There are many ways to configure profiles:
Most famous once involve using an application.properties file or a yaml file. About which you can read more here:
Spring boot also provides handy annotations as simple as using @ActiveProfiles to choose which configuration to run.
@ActiveProfiles("dev")The above code will automatically select dev profile and use configurations provided in application-dev.properties file for you.
Simple enough.
Moving on, we want to avoid hard-coding as much as possible especially for credentials, server names etc in our application.properties file.
The apparent solution here is to use environment variables.
So how do we do it in spring boot?
Spring boot provides us with the value annotation to achieve this task merely with a single annotation
@ValueLet’s see how to use this:
We have our EmailService here, which sends our emails for us.
Using @value annotation in EmailService:
@Service //marks class as spring service
class EmailService{
@Value("${SMTP_SERVER_PORT:-1}") //read SMTP_SERVER_PORT env var
private String SMTP_SERVER_PORT; //assign the value to this field
@Value("${SMTP_SERVER_HOST:NA}")
private String SMTP_SERVER_HOST;
@Value("${SMTP_USER_NAME:NA}")
private String SMTP_USER_NAME;
@Value("${SMTP_USER_PASSWORD:NA}")
private String SMTP_USER_PASSWORD;public void send(EmailTemplate template, String receiverEmailId){/*email sending code*/
}
}
@Value annotation checks if there is an environment variable present with the same name and if it finds it, it assigns that value to the respective field.
For eg :
@Value("${SMTP_USER_PORT:-1}")
private String SMTP_SERVER_PORT;We look for the environment variable with the name SMTP_SERVER_PORT and if it is present we assign it’s value to field underneath it.
Note : Environment variable and the field name can be different from one another.
Environment Variables in application.properties
You can also assign some default values to these fields in application.properties
On your application classpath (e.g. inside your jar) you can have an
application.propertiesthat provides a sensible default property value forSMTP_SERVER_PORT. When running in a new environment, anapplication.propertiescan be provided outside of your jar that overrides theSMTP_USER_PORT
So now everything is in place and works fine, you are successfully reading environment variables and using them.
If you want to read about writing integrations tests for a class which reads values from environment variables please refer to my article on:
Spring Boot : Integration tests with environment variables
Hope you learned something interesting.
Happy Coding!!!
