springcontext-env is a lightweight, no-dependency (no deps) environment variables loader for Spring applications. It can be used in both standalone Spring applications or Spring Boot-powered applications. By Spring standalone, we mean applications that do not use Spring Boot auto-configurations.
This library loads dotenv variables or properties from .env files. It allows you to define several .env files for your application configurations—for example, .env-dev, .env-prod, .env-test, etc. Essentially, the library will look for any files that start with .env. However, it will not do this automatically unless the .env files are located at the root directory of the project.
There are several ways to tell the library where to look for your .env files:
-
Add a file called
dotenv.propertiesin your project's resources folder.This properties file will specify a full directory path that contains the
.envfiles, and an (optional) list of actual file names you would like to load and use within your application.-
If you don't specify the actual
.envfiles to load, the library will, by default, load all the available files in the provided directory that start with.env. -
If the filenames to be used are specified in
dotenv.properties, then only those files will be loaded. In this case, you can name yourenvfiles any name you want; they don't have to be prefixed with.env. -
Example
dotenv.propertiesfile content-
Windows
ENV_DIR_PATH=L:\\Lab\\apps\\configurations FILE_TEST=test.config FILE_PROD=prod
NOTE: It is very important to use\\when defining paths on Windows Environment. Otherwise you will getNoSuchFileExceptionError.
-
Unix
ENV_DIR_PATH=/home/var/configurations FILE_TEST=test.config FILE_PROD=prod
-
-
Remember that file name in the
dotenv.propertiesmust start withFILE_followed by any letter or names you like. The variableENV_DIR_PATHis case sensitive in UNIX. We recommend you maintain the uppercasing format.
-
-
Add a system environment variable
-
ENV_DIR_PATHin your system. You can specify to this library where you what it to load the.envfiles from by adding an ENV_DIR_PATH in your system. Follow your spefic system intstructions on how to add an environment variable. -
Ensure that the directory path you specified is a full path and can be accessed by the application that uses this library. Again any files in the provided directory that starts with
.envwill be loaded. You can override this behaviour by specifying the files you want loaded in thedotenv.properties. -
Examples
- Unix:
export ENV_DIR_PATH=/home/var/configurations - Windows:
SET ENV_DIR_PATH=L:\\Lab\\apps\\configurationsNOTE: It is very important to use\\when defining paths on Windows Environment. Otherwise you will getNoSuchFileExceptionError.
- Unix:
-
-
Add .env files in the project root directory.
-
This is the default behavior, and the library will look for any
.envfiles in the project sources root dir. This is mainly for development or test purposes. -
However, it is recommended to use the first two options when creating a production-grade app. The above two options assume that your env files are somewhere in your file system and not in the project source code files.
- If you are using this default behavior, ensure to add your
.envfiles in the.gitignoreso that they don't get pushed into the source control system.
- If you are using this default behavior, ensure to add your
-
-
For
Spring Bootapplications, just include this library as part of your project and you are done; no configurations needed. -
For the
Non-Spring Bootapplications, you will need to do a little configuration; you will need to add an initializer in your application. The following is a configuration for non-Spring Boot apps.
Non-Web Spring applications
@Configuration
public class MyConfiguration {
@Bean
public static PropertySourcesPlaceholderConfigurer placeholderConfigurer(){
return new PropertySourcesPlaceholderConfigurer();
}
}
public class Main(String []args) {
try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext()) {
// Initialize the SpringContext Env Loader Application context initializer
SpringContextEnvApplicationContextInitializer initializer = new SpringContextEnvApplicationContextInitializer();
initializer.initialize(context);
// Now register your classes
context.register(MyConfiguration.class);
context.refresh();
}
}Spring web applications
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com")
public class AppConfig {
// Your beans and other configurations
}
public class MyWebAppInitializer implements WebApplicationInitializer {
@Override
public void onStartup(@NonNull ServletContext servletContext) throws ServletException {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
SpringContextEnvApplicationContextInitializer env = new SpringContextEnvApplicationContextInitializer();
env.initialize(context);
}
}- Remember that
WebApplicationInitializerimplementations are detected automatically. So, once you define one, you are good to go.
The following are some of the considerations that we have made:
-
Incomplete definitions are ignored.
- The tooling will ignore incomplete defined variables. An example of incomplete variables include:
KEY KEY= KEY=${} KEY=${ } KEY=${ ""However, when there is an existing System Variable defined with such
KEY, then the value of the system variable will be used. So, you are free to define a system variable and tell the library to load it by including it in the.envfile.This tooling reguard
${}or${ }as an empty variable value and therefore, ignored. The${is consired a bad variable defintion format and therefore, ignored.Also, we are of an opinion that it is not a good practice to have your configurations use empty passwords. So, if you define something like this:
DB_NAME=test USERNAME=doe PASSWORD=""
The
PASSWORDveriable will not be loaded, it will be ignored. That means if your configurations rely on the loaded.envproperties thenPASSWORDproperty will not be accessible because it is not loaded. The logs will tell you that such property is not loaded because it is not defined. -
Circular dependecies:
- When there is a circular dependency amongst the variables in
.envfile, then the application will immediately halt by throwing an EnvContextLoaderException. A circular dependency looks like this:
KEY=VAR VAR=${KEY} - When there is a circular dependency amongst the variables in
-
Property definitions:
- There are several ways you can define your variables in the
.envfiles:
- Space or Tab separated
KEY VALUE KEY VALUE - Assignment Operator
KEY=VALUE KEY = VALUE - Collon separated
KEY:VALUE KEY : VALUE - Variable referencing
USERNAME=jdoe PASSWORD=p@word DB_NAME=test HOST=localhost PORT=3306 URL=jdbc:mysql://${HOST}:${PORT}/${DB_NAME}
- There are several ways you can define your variables in the
-
Under the hood we are using
java.util.PropertiesAPI to parse the.envfiles. The files should beUTF-8compatible.
Add the tooling to your application dependecies. The easiest way is to source from mave central repository and add to your build tool.
The current version is 1.1.4
- Using gradle
implementation group: 'io.sysr', name: 'springcontext-env', version: 1.1.4 - Using Apache Maven
<dependency> <groupId>io.sysr</groupId> <artifactId>springcontext-env</artifactId> <version>1.1.4</version> </dependency> - Remember: For
Spring bootapplications, only include this library as part of your project. No additional configurations are needed. It will integrate seamlessly with your application.
Note: It's important to keep your .env files secure, as they may contain sensitive information like API keys and passwords. These files should not be committed to source control systems like Git to prevent exposing sensitive data.
-
For containerized applications, you can manage environment variables efficiently by using a shared volume. Here’s how you can set it up:
-
Define ENV_DIR_PATH:
- Ensure that your container knows about an optional
ENV_DIR_PATHvariable that the user can provide when starting the container. Remember thatENV_DIR_PATHpoints at the directory where your.envfiles are located. It should not point at your.envfile.
- Ensure that your container knows about an optional
-
Example Docker Configuration:
# Dockerfile # Use a base image FROM openjdk:21-jdk-slim # Copy the application files COPY target/myapp.jar /app/myapp.jar # Define the ENV_DIR_PATH environment variable ENV ENV_DIR_PATH=/path/to/env # Run the application CMD ["sh", "-c", "source $ENV_DIR_PATH/.env && java -jar /app/myapp.jar"]
-
-
Centralized Management
- This env loader library provides a single, consistent place to define and manage environment variables, making it easier to maintain and update configurations.
-
Security
- By loading environment variables from a secure location, you can avoid hardcoding sensitive information like API keys and passwords directly in your codebase, reducing the risk of accidental exposure.
-
Portability
- Environment variables can be easily ported across different environments (development, testing, production) without changes to the application code. This ensures consistency and reduces configuration errors.
-
Ease of Use
- The library easily integrates with your spring boot application. No configurations needed.
If you would like to contribute to the continual maintaince and improvement of this tooling, please refer to the CONTRIBUTING.MD for more information.
You are happy with the work done so far? Please remember to support the creative minds behind this tooling by sharing with them some coffee Sponsor