Recently, while working on a job, I ran into an interesting problem with Spring Boot: the configuration files I had defined using the @PropertySource
annotation were being overridden by the application.properties
file, which I had also defined with a @PropertySource
annotation. Why wasn't Spring prioritizing my configuration files correctly?
What I was attempting to accomplish was shipping my jar
with some default configuration options that were mostly tailored for my local development setup, and then being able to specify an external configuration file for staging and production that would override the values accordingly. I got the idea from a project I used from GitHub called Acrarium, but unfortunately I didn't quite take the time to slow down and understand what was going on before attempting to implement something similar myself.
I came to the realization that something was wrong because while testing deployments with some docker containers locally, my Spring Boot app was crashing since it couldn't connect to the databse. I spent hours trying to figure out why Spring Boot container couldn't connect to the MySQL container, going as far as installing the MySQL command line client to manually verify that the containers were in fact connected and able to communicate with each other. That of course wasn't the problem, so I took to StackOverflow to find some answers.
I discovered that you can pass in an argument to the application while running it as a jar, specifically -spring.config.location
, and while it fixed my issue, I wasn't satisfied with this because I still didn't understand what the original problem was, and I wasn't content to just shrug my shoulders and move along. It was only through searching around a bit more that I stumbled upon the Spring Boot documentation page for externalized configuration when I realized my mistake. If you look towards the bottom of this list, item #15 at the time of writing, is the application.properties
file and following it with one level lower in priority for Spring, is the @PropertySource
annotation configuration files.
The solution, then, was to rename my application.properties
file to something else, and add that new file inside another @PropertySource
annotation on my Application
class, and problem solved! Yet another case of the problem lying between the chair and keyboard. Had I read through the source a little closer with the Acrarium project, from which I took the inspiration for this setup, I would have noticed that they weren't using the application.properties
file to define overridable defaults, but rather a default.properties
file. Lesson learned here: slow down and read the source, make sure you understand it and can explain what's going on, and then try to imitate it in your own works.