Persistent @ConfigurationProperties with EnvironmentPostProcessor in Spring Boot

Color King (cut) by František Kupka
@ConfigurationProperties("hello")
@Getter
@Setter
class HelloConfigurationProperties {
private String greeting = "Hello!";
}
@RestController
@RequestMapping("/hello")
@AllArgsConstructor
class HelloController {
private String greeting; @GetMapping
public String sayHello() {
return this.greeting;
}
}
$ curl http://localhost/hello
> Hello!
HELLO_GREETING=Hi!// restart the application...$ curl http://localhost/hello
> Hi!
// ...
class HelloController {
// ...
@PutMapping
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!
@RequiredArgsConstructor
public class Properties {
private final JdbcTemplate jdbcTemplate; public void store(String name, Object value) {
jdbcTemplate.update(
"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"),
(String)m.get("value")))
.collect(Collectors.toSet());
}
}
// ...
class HelloController {
private final Properties properties; // ... @PutMapping
public ResponseEntity updateGreeting(String greeting) {
this.greeting = greeting;
this.properties.store("hello.greeting", greeting);
return new ResponseEntity(HttpStatus.NO_CONTENT);
}
}
class ConfigurationPropertiesFromDatabasePostProcessor 
implements EnvironmentPostProcessor, Ordered {
@Override
public void postProcessEnvironment(
ConfigurableEnvironment env, SpringApplication app) {
try {
DataSource dataSource = DataSourceBuilder
.create()
.url(env.getProperty("spring.datasource.url"))
.username(env.getProperty("spring.datasource.username"))
.password(env.getProperty("spring.datasource.password"))
.driverClassName(env.getProperty("spring.datasource.driver-class-name"))
.build();
env.getPropertySources().addLast(
new MapPropertySource(
"propertiesFromDatabase",
new Properties(new JdbcTemplate(dataSource))
.all().stream()
.collect(Collectors.toMap(
Property::getName, Property::getValue))));
} catch (BadSqlGrammarException ignore) {
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public int getOrder() {
return Ordered.LOWEST_PRECEDENCE;
}
}
org.springframework.boot.env.EnvironmentPostProcessor=\
com.ttulka.ConfigurationPropertiesFromDatabasePostProcessor

--

--

--

Software developer and occasional blogger: https://blog.ttulka.com

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Sneak Peek at 2020 Volume 3: Flutter

Sneak Peek at 2020 Volume 3: Flutter

Setting up mTLS and Kestrel (cont.)

Ensuring good service health by automating thorough integration testing and alerting

Review — Coursera’s Google IT Support Professional Certification in 2022, Should You Take it?

Review — Coursera’s Google IT Support Professional Certification

Roketo’s co-founder selects the winners of the MetaBUILD 2.0 hackathon

The mystery behind CLI interpreter — A deeper look into how CLIs work

[365Gist] Repeating session via Cookies — Selenium (Python)

Jmeter performance testing with different grant types offered by WSO2 APIM — Part…

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
Tomas Tulka

Tomas Tulka

Software developer and occasional blogger: https://blog.ttulka.com

More from Medium

Introduction to SPRING AOP

Extra-Strenght Chapter 5

Chapter 02 — Classes and Objects

Spring boot Starter Project In STS