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.

Color King (cut) by František Kupka

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

class HelloConfigurationProperties {
private String greeting = "Hello!";

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

class HelloController {
private String greeting; @GetMapping
public String sayHello() {
return this.greeting;

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

$ curl http://localhost/hello
> Hello!

The message can be changed by setting an environment variable:

HELLO_GREETING=Hi!// restart the application...$ curl http://localhost/hello
> Hi!

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

// ...
class HelloController {
// ...
public ResponseEntity updateGreeting(String greeting) {
this.greeting = greeting;
return new ResponseEntity(HttpStatus.NO_CONTENT);
$ curl http://localhost/hello?greeting=Ahoy! -X PUT
$ curl http://localhost/hello
> Ahoy!

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

public class Properties {
private final JdbcTemplate jdbcTemplate; public void store(String name, Object value) {
"UPDATE app_properties SET value = ? WHERE name = ?",
value, name);
public Set all() {
return jdbcTemplate.queryForList(
"SELECT name, value FROM app_properties").stream()
.map(m -> new Property((String)m.get("name"),

And use it in the controller:

// ...
class HelloController {
private final Properties properties; // ... @PutMapping
public ResponseEntity updateGreeting(String greeting) {
this.greeting = greeting;"hello.greeting", greeting);
return new ResponseEntity(HttpStatus.NO_CONTENT);

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:

class ConfigurationPropertiesFromDatabasePostProcessor 
implements EnvironmentPostProcessor, Ordered {
public void postProcessEnvironment(
ConfigurableEnvironment env, SpringApplication app) {
try {
DataSource dataSource = DataSourceBuilder
new MapPropertySource(
new Properties(new JdbcTemplate(dataSource))
Property::getName, Property::getValue))));
} catch (BadSqlGrammarException ignore) {
} catch (Exception e) {
throw new RuntimeException(e);
public int getOrder() {

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:

Software developer and occasional blogger: