Persistent @ConfigurationProperties with EnvironmentPostProcessor in Spring Boot

Configuration properties is a great feature in Spring Boot. In a monolithic long-time running application, we often want to change the application settings. Those changes must be persisted to survive the application restart.

We can use environment post-processing for that. This post describes how.

Image for post
Image for post
Color King (cut) by František Kupka

Let’s start slowly; consider a simple class with configuration properties:

The property of greeting is used to print a greeting message from a REST controller:

After building and starting the application, we can see the default greeting to be printed:

The message can be changed by setting an environment variable:

As our application can’t be restarted easily (there are such cases!), we introduce a new endpoint to update the greeting message:

Now it’s time to think about persistence. We introduce a class persisting properties into a database:

And use it in the controller:

Now we have the changes in the database. The last step is to fill the configuration properties at the startup. It’s where the environment post-processor comes to shine:

Probably the biggest gotcha is the need to create a new data-source. As the environment post-processor runs before application context is refreshed, there are no ready-to-use beans so far. We have to create everything we need from scratch.

Properties from the database are loaded and put as a new property-source with the lowest priority — this means, we can still overwrite them using environment variables, system properties etc. If this behavior is not desired, we can change the order by using addFirst, addBefore or addAfter.

We have to add the post-processor entry into META-INF/spring.factories:

That’s it! Our configuration changes now survive a restart of the application.

You can find a working example on my GitHub.

The idea is also implemented in this small Spring Boot tool:

Written by

Software developer and occasional blogger:

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store