Although you may find many different ways to work with configuration in Spring Boot applications, across the industry
there is one most common simple practice that results in reasonably flexible and maintainable solutions. I will try to outline it below without going too deep into exploring all possible options, just to make it short and quick to read.
1. Inject environment variables to your components with @Value
The configuration will be injected by Spring components, but it has to be annotated with @Value:
@Component
class MyComponent {
@Value("${myappname.weatherapi.url}")
private weatherApiUrl
// ...
}
Also myappname.weatherapi.url
have to be defined in application.properties
(or application.yaml
):
myappname.weatherapi.url=http://weather.com/api
1.1 Override it in tests
You can override it in tests easily
by re-specifying this @Value within the test:
@SpringBootTest(properties = {
"myappname.weatherapi.url=http://localhost:8888"
})
class MyComponentTest {
@Autowired
private MyComponent myComponent;
// ..
}
2. Inject environment variables into application.properties
If you have variables defined in your environment with
export WEATHER_URL=http://wiremock:8000
when you run Spring Boot application,
it can be injected into application.properties
using this syntax:
server.port=${PORT:8020}
myappname.wetherapi.url=${WEATHER_URL:http://localhost:8888}
Now when you run your Spring Boot application,
and if you have your PORT and WEATHER_APPLICATION set in your environment,
then the environment variables will be in use.
But if you don't have them in the environment where you run your application,
then it will fall back to default values (8020 and localhost).
3. Alternative locations for application.properties file
By default application.properties
is used. But if Spring Boot profile is set then it will use a filename of this pattern: application-{profilename}.properties
.
to run your Spring Boot app with another profile make sure you pass "-D" param like:
java -jar -Dspring-boot.profile=local my-spring-boot-app.jar
this will use application-local.properties
.
3.1 Override it just for tests
To use file aplication-test.properties
in on test class use:
@SpringBootTest
@ActiveProfiles("test")
class MyComponentTest {
// ...
}
- Bypassing application (Bad Practice)
Your components could use the SystemProperties
class to access environment variables directly.
In this way, you don't even need to have anything in application.properties
.
But the best practice is to use properties files,
as this way it is clear what parameters could be tuned for this service. And given that your properties files are injecting environment variables, then your application is truly portable
because Java code does not care really how the values get injected. So this allows us to even migrate away from Spring, or from using environment if that becomes a necessity.
5. Adhere 12 Factor App methodology
It is worth mentioning that using multiple properties files
for each deployment environment, while it may seem tempting to do, may not necessarily be the best idea. The reasoning is
quite clearly defined in 12 Factor methodology. This way you make sure that your application is platform-agnostic and can be easily deployed in many different environments (including containers) without changes in the code.
Although there are thousands of different ways to manage the configuration in Spring Boot applications, all you need to know
is to follow these simple 5 steps to make sure your applications
are flexible and scaleable and cloud-ready.
Top comments (0)