Loading environmental values into class is almost always necessary for commercial applications, e.g. loading stage configuration of delivery pipeline. With DI library such as Guice, loading environmental variables can be hidden inside the module class.
Let’s see the simplest example. We have 2 classes both of which just load the environmental values and return the message string with it. There are slight difference in how they load the value.
- ClassWithEnv: Loading environmental variables directly with
- ClassWithInjectedEnv: Using Guice to load the value of the environmental variables.
Which implementation is better ? I think most people agree that using
System.getenv() directly in the logic class is not preferable because an environmental variable is essentially a global variable. With the help of DI library, we can encapsulate environmental variables inside the module class and use it through normal dependency injection, which makes codes more modular and unit testable.
This pattern is simple but quite strong. For example, you might want to add configuration files in your repository and read them according to the environmental variables. This configuration loading logic can be also placed in the module class. This way, you can avoid polluting your business logic with environment specific constants.
To eliminate the use of “string” and enjoy the benefit of type system, you can use BindingAnnotation
The version with bindingAnnotation is shown below. Only added/changed classes are shown.