Mutable persistent configuration properties that survive an application restart.
Extendable store types. JDBC store as default.
<dependency>
<groupId>com.ttulka.spring.boot.configstore</groupId>
<artifactId>configuration-properties-store-jdbc-spring-boot-starter</artifactId>
<version>1.4.0</version>
</dependency>
The application environment must contain data source configuration properties.
For example in application.yml:
spring:
datasource:
url: jdbc:h2:./mydb
driverClassName: org.h2.Driver
username: sa
password:@Autowired
ConfigurationStore configStore;
...
configStore.update("my-property", "value123");Will be persisted and loaded at the next application startup:
@ConfigurationProperties
@Getter
@Setter
public class SampleProperties {
private String myProperty;
}Processing of the property update is done via application events, these are synchronous by default.
You can enable running async mode by annotation one of your configurations with @EnableAsync.
spring.configstore.prefix(default:null)- Prefix added to a property name:
<prefix>.<propName>. - When
null, no prefix is added. - String value.
- Prefix added to a property name:
spring.configstore.source.last(default:false)- The property source is added as last, otherwise as first.
- Boolean value.
spring.configstore.jdbc.enabled(default:true)- JDBC-based store is enabled/disabled.
- Boolean value.
spring.configstore.jdbc.schema(default:null)- Schema for the property store database table.
- When not set (
null) will use the default schema. - String value.
spring.configstore.jdbc.table(default:configstore_properties)- Database table name for the property store.
- When a schema set will result into
<schema>.<table>. - String value.
As well as for configuration properties, custom converters can be added. To each custom converter there must be an inverted converter:
@Component
@ConfigurationPropertiesBinding
class EmployeeConverter implements Converter<String, Employee> {
@Override
public Employee convert(String from) {
String[] data = from.split(",");
return new Employee(data[0], Double.parseDouble(data[1]));
}
}
@Component
@ConfigurationPropertiesBinding
class EmployeeInvertedConverter implements Converter<Employee, String> {
@Override
public String convert(Employee from) {
return from.firstName() + "," + from.lastName();
}
}Then, the class could be used in configuration properties as well as in configuration store:
@ConfigurationProperties
public class SampleProperties {
private Employee employee;
...
}
...
configStore.update("employee", new Employee("Homer", "Simpson"));There are several interfaces to be implemented for customizing the store.
-
ConfigurationPropertiesStore-
The default implementation publishes an event.
-
The entry point, should be autowired in the application.
@Autowired ConfigurationStore configStore; configStore.update("my-prop", 123);
-
-
ConfigurationStoreEventPublisher-
The default implementation uses Spring's
ApplicationEventPublisher. -
Could be extended together with an event handling that calls
ConfigurationStoreEventListener:@Bean ConfigurationStoreEventPublisher applicationConfigurationStoreEventPublisher( ApplicationEventPublisher publisher) { return publisher::publishEvent; }
And:
@Component @RequiredArgsConstructor class ConfigurationPropertyUpdatedEventListener { private final ConfigurationStoreEventListener configurationStoreEventListener; @EventListener void handleEvent(ConfigurationPropertyUpdated event) { configurationStoreEventListener.on(event); } }
-
mvn clean install
So far there is the following implementation:
- JDBC
com.ttulka.spring.boot.configstore:configuration-properties-store-jdbc-spring-boot-starter
Then implementing a new extension, at least ConfigurationStoreEventListener must be implemented.
Next, a new implementation of ConfigurationStorePostProcessor is needed to load properties into the environment.