Dynamically Change Application.Properties Values in Spring Boot

spring boot : How to set spring properties dynamically

Since you know the properties to enable SSL in the spring boot app. You can pass these properties programmatically in your spring boot application like this:

@SpringBootApplication
public class SpringBootTestApplication {
public static void main(String[] args) {

// SpringApplication.run(SpringBootTestApplication.class, args);

Properties props = new Properties();
props.put("server.ssl.key-store", "/home/ajit-soman/Desktop/test/keystore.p12");
props.put("server.ssl.key-store-password", "123456");
props.put("server.ssl.key-store-type", "PKCS12");
props.put("server.ssl.key-alias", "tomcat");

new SpringApplicationBuilder(SpringBootTestApplication.class)
.properties(props).run(args);
}
}

As you can see I have commented out this:
SpringApplication.run(SpringBootTestApplication.class, args);
and used SpringApplicationBuilder class to add properties to the app.

Now, these properties are defined in the program, You can apply condition and change property values based on your requirements.

Programatically changing the application.properties file at runtime with Spring Boot

The /actuator/refresh endpoint will do the job.
You need to annotate your class (the one that holds the property you want to reload) with the @RefreshScope annotation.

So basically modify your application.properties file, then invoke that endpoint and its done.

Please find this link with more info about the actuator.

This other link with more details on @RefreshScope.

Load dynamic objects from application.properties in Spring Boot

By playing around a little bit, I managed to solve the issue. I reverted my class back to Kotlin, and made some adjustments on how I retrieve the values. This is how you can load dynamic objects from application.properties in Spring Boot with Kotlin:

Suppose you have an object class called Store.kt

data class Store(
var name: String ?= null,
var username: String ?= null,
var password: String ?= null,
var hostname: String ?= null,
var port: Int ?= null,
)

In your application.properties

system.stores.Store1.name=Test1
system.stores.Store1.username=test1
system.stores.Store1.password=123456
system.stores.Store1.hostname=12.34.56.78
system.stores.Store1.port=1234

system.stores.Store2.name=Test2
system.stores.Store2.username=test2
system.stores.Store2.password=123456
system.stores.Store2.hostname=12.34.56.78
system.stores.Store2.port=1234

This is in your StoresConfiguration.kt

@Configuration
@ConfigurationProperties(prefix = "system")
class StoreConfiguration(
var stores: HashMap<String, Store> = HashMap()
) {

fun getStore(storeName: String) : Store? {
return stores.get(storeName)
}


}

Then suppose you want to get the objects and use them in one of your service classes:

@Service
class StoreService(

private val storeConfiguration: StoreConfiguration,

) {

fun test() {

val MyStore = storeConfiguration.getStore("Store1")

if (MyStore != null) {

// Do whatever you want to do with your object

} else {

// If your object does not exist

}

}

}

Dynamically change application.properties values in spring boot

As @moilejter suggests, one possible way is to persist in database table and at start time you simply read from that table instead of application.properties file. Your application.properties files can hold information necessary for database connection.

You would also need a JMX method or a REST API to trigger in your application that the url has changed and which inturn, would simply read from same table. This way you would be safe even if app restarts and you won't lose the override.

You can use BeanFactoryPostProcessor coupled with Environment bean to leverage spring placeholder concept.



Related Topics



Leave a reply



Submit